@c -*- coding: utf-8; mode: texinfo; documentlanguage: fr -*-
@ignore
- Translation of GIT committish: c299f84d574ac9b97ab7ffbb640b5c3a1cdca5cc
+ Translation of GIT committish: 3c62ac104645533873bba800f7b0f371089f535a
When revising a translation, copy the HEAD committish of the
version that you are working on. For details, see the Contributors'
Guide, node Updating translation committishes..
@end ignore
-@c \version "2.14.0"
+@c \version "2.15.18"
-@c Translators: Valentin Villenave
-@c Translation checkers: Gilles Thibault, Jean-Charles Malahieude
+@c Translators: Valentin Villenave, Jean-Charles Malahieude
+@c Translation checkers: Gilles Thibault
-
-@node Interfaces pour les programmeurs
-@chapter Interfaces pour les programmeurs
+@node Interfaces pour programmeurs
+@chapter Interfaces pour programmeurs
@translationof Interfaces for programmers
-@untranslated
-
+Advanced tweaks may be performed by using Scheme. If you are
+not familiar with Scheme, you may wish to read our
+@ref{Tutoriel Scheme}.
@menu
+* Blocs de code Lilypond::
+* Fonctions Scheme::
* Fonctions musicales::
-* Interfaces de programmation::
-* Construction de fonctions complexes::
-* Interface de programmation des marqueurs de texte::
+* Fonctions événementielles::
+* Fonctions pour markups::
* Contextes pour programmeurs::
-* Utilisation de procédures Scheme en tant que propriétés::
-* Utilisation de code Scheme au lieu de \"tweak\"::
+* Fonctions de rappel::
+* Code Scheme intégré::
* Retouches complexes::
@end menu
-@node Fonctions musicales
-@section Fonctions musicales
-@translationof Music functions
+@node Blocs de code Lilypond
+@section Blocs de code Lilypond
+@translationof Lilypond code blocks
+
+@untranslated
+
+
+@node Fonctions Scheme
+@section Fonctions Scheme
+@translationof Scheme functions
+
+@cindex Scheme, fonctions (syntaxe LilyPond)
@untranslated
@menu
-* Aperçu des fonctions musicales::
-* Fonctions de substitution simple::
-* Fonctions de substitution par paire::
-* De l'usage des mathématiques dans les fonctions::
-* Fonctions fantômes::
-* Fonctions dépourvues d'argument::
-* Liste des fonctions musicales prédéfinies::
+* Définition de fonctions Scheme::
+* Utilisation de fonctions Scheme::
+* Fonctions Scheme fantômes::
@end menu
-@node Aperçu des fonctions musicales
-@subsection Aperçu des fonctions musicales
-@translationof Overview of music functions
+@node Définition de fonctions Scheme
+@subsection Définition de fonctions Scheme
+@translationof Scheme function definitions
+
+@funindex define-scheme-function
@untranslated
-@node Fonctions de substitution simple
-@subsection Fonctions de substitution simple
-@translationof Simple substitution functions
+@node Utilisation de fonctions Scheme
+@subsection Utilisation de fonctions Scheme
+@translationof Scheme function usage
@untranslated
-@node Fonctions de substitution par paire
-@subsection Fonctions de substitution par paire
-@translationof Paired substitution functions
+@node Fonctions Scheme fantômes
+@subsection Fonctions Scheme fantômes
+@translationof Void scheme functions
+@funindex define-void-function
+@funindex \void
@untranslated
-@node De l'usage des mathématiques dans les fonctions
-@subsection De l'usage des mathématiques dans les fonctions
-@translationof Mathematics in functions
+@node Fonctions musicales
+@section Fonctions musicales
+@translationof Music functions
+
+@cindex musicale, fonction
@untranslated
+@menu
+* Définition de fonctions musicales::
+* Utilisation de fonctions musicales::
+* Fonctions de substitution simple::
+* Fonctions de substitution intermédiaires::
+* De l'usage des mathématiques dans les fonctions::
+* Fonctions dépourvues d'argument::
+* Fonctions musicales fantômes::
+@end menu
+
-@node Fonctions musicales fantômes
-@subsection Fonctions musicales fantômes
-@translationof Void music functions
+@node Définition de fonctions musicales
+@subsection Définition de fonctions musicales
+@translationof Music function definitions
+
+@cindex defining music functions
+@funindex define-music-function
@untranslated
-@node Fonctions dépourvues d'argument
-@subsection Fonctions dépourvues d'argument
-@translationof Functions without arguments
+@node Utilisation de fonctions musicales
+@subsection Utilisation de fonctions musicales
+@translationof Music function usage
@untranslated
-@node Liste des fonctions musicales prédéfinies
-@subsection Liste des fonctions musicales prédéfinies
-@translationof Overview of available music functions
+@node Fonctions de substitution simple
+@subsection Fonctions de substitution simple
+@translationof Simple substitution functions
@untranslated
-@include identifiers.tely
-@node Interfaces de programmation
-@section Interfaces de programmation
-@translationof Programmer interfaces
+@node Fonctions de substitution intermédiaires
+@subsection Fonctions de substitution intermédiaires
+@translationof Intermediate substitution functions
@untranslated
-@menu
-* Variables d'entrée et Scheme::
-* Représentation interne de la musique::
-@end menu
-
-@node Variables d'entrée et Scheme
-@subsection Variables d'entrée et Scheme
-@translationof Input variables and Scheme
+@node De l'usage des mathématiques dans les fonctions
+@subsection De l'usage des mathématiques dans les fonctions
+@translationof Mathematics in functions
@untranslated
-@node Représentation interne de la musique
-@subsection Représentation interne de la musique
-@translationof Internal music representation
+@node Fonctions dépourvues d'argument
+@subsection Fonctions dépourvues d'argument
+@translationof Functions without arguments
@untranslated
-@node Construction de fonctions complexes
-@section Construction de fonctions complexes
-@translationof Building complicated functions
+@node Fonctions musicales fantômes
+@subsection Fonctions musicales fantômes
+@translationof Void music functions
@untranslated
-@menu
-* Affichage d'expressions musicales::
-* Propriétés de la musique::
-* Exemple : redoubler une note avec liaison::
-* Exemple : ajouter une articulation à plusieurs notes::
-@end menu
+@node Fonctions événementielles
+@section Fonctions événementielles
+@translationof Event functions
-@node Affichage d'expressions musicales
-@subsection Affichage d'expressions musicales
-@translationof Displaying music expressions
+@funindex define-event-function
+@cindex event functions
@untranslated
-@node Propriétés de la musique
-@subsection Propriétés de la musique
-@translationof Music properties
+@node Fonctions pour markups
+@section Fonctions pour @emph{markups}
+@translationof Markup functions
@untranslated
+@menu
+* Construction d'un markup en Scheme::
+* Fonctionnement interne des markups::
+* Définition d'une nouvelle commande de markup::
+* Définition d'une nouvelle commande de liste de markups::
+@end menu
-@node Exemple : redoubler une note avec liaison
-@subsection Exemple : redoubler une note avec liaison
-@translationof Doubling a note with slurs (example)
+
+@node Construction d'un markup en Scheme
+@subsection Construction d'un @emph{markup} en Scheme
+@translationof Markup construction in Scheme
+
+@cindex defining markup commands
@untranslated
-@node Exemple : ajouter une articulation à plusieurs notes
-@subsection Exemple : ajouter une articulation à plusieurs notes
-@translationof Adding articulation to notes (example)
+@node Fonctionnement interne des markups
+@subsection Fonctionnement interne des @emph{markups}
+@translationof How markups work internally
@untranslated
-@node Interface de programmation des marqueurs de texte
-@section Interface de programmation des marqueurs de texte
-@translationof Markup programmer interface
+@node Définition d'une nouvelle commande de markup
+@subsection Définition d'une nouvelle commande de @emph{markup}
+@translationof New markup command definition
@untranslated
-
@menu
-* Construction Scheme d'un marqueur::
-* Fonctionnement interne des marqueurs::
-* Définition d'une nouvelle commande de marqueur::
-* Définition d'une nouvelle commande de liste de marqueurs::
+* Syntaxe d'une commande markup::
+* Attribution de propriétés::
+* Exemple commenté::
+* Adaptation d'une commande incorporée::
@end menu
-@node Construction Scheme d'un marqueur
-@subsection Construction Scheme d'un marqueur
-@translationof Markup construction in Scheme
+
+@node Syntaxe d'une commande markup
+@unnumberedsubsubsec Syntaxe d'une commande @emph{markup}
+@translationof Markup command definition syntax
@untranslated
-@node Fonctionnement interne des marqueurs
-@subsection Fonctionnement interne des marqueurs
-@translationof How markups work internally
+@node Attribution de propriétés
+@unnumberedsubsubsec Attribution de propriétés
+@translationof On properties
@untranslated
-@node Définition d'une nouvelle commande de marqueur
-@subsection Définition d'une nouvelle commande de marqueur
-@translationof New markup command definition
+@node Exemple commenté
+@unnumberedsubsubsec Exemple commenté
+@translationof A complete example
@untranslated
-@node Définition d'une nouvelle commande de liste de marqueurs
-@subsection Définition d'une nouvelle commande de liste de marqueurs
+@node Adaptation d'une commande incorporée
+@unnumberedsubsubsec Adaptation d'une commande incorporée
+@translationof Adapting builtin commands
+
+@untranslated
+
+
+@node Définition d'une nouvelle commande de liste de markups
+@subsection Définition d'une nouvelle commande de liste de @emph{markups}
@translationof New markup list command definition
@untranslated
@translationof Contexts for programmers
@untranslated
-
-
@menu
* Évaluation d'un contexte::
* Application d'une fonction à tous les objets de mise en forme::
@end menu
+
@node Évaluation d'un contexte
@subsection Évaluation d'un contexte
@translationof Context evaluation
+@cindex calling code during interpreting
+@funindex \applyContext
+
@untranslated
@subsection Application d'une fonction à tous les objets de mise en forme
@translationof Running a function on all layout objects
+
+@cindex calling code on layout objects
+@funindex \applyOutput
+
@untranslated
-@node Utilisation de procédures Scheme en tant que propriétés
-@section Utilisation de procédures Scheme en tant que propriétés
-@translationof Scheme procedures as properties
+@node Fonctions de rappel
+@section Fonctions de rappel
+@translationof Callback functions
@untranslated
-@menu
-* Utilisation de code Scheme au lieu de \"tweak\"::
-* Retouches complexes::
-@end menu
+@node Code Scheme intégré
+@section Code Scheme intégré
+@translationof Inline Scheme code
-@node Utilisation de code Scheme au lieu de \"tweak\"
-@section Utilisation de code Scheme au lieu de @code{\tweak}
-@translationof Using Scheme code instead of tweak
+TODO: the example for this section is ill-chosen since
+@example
+F = -\tweak #'font-size #-3 -\flageolet
+@end example
+(note the @samp{-} marking it as a post event) will actually work fine
+for the stated purpose. Until this section gets a rewrite, let's
+pretend we don't know.
L'inconvénient principal de la commande @code{\tweak} est la rigidité de
sa syntaxe. Par exemple, le code suivant produit une erreur.
C'est en se servant du langage Scheme que l'on peut résoudre ce
problème. Dans cet exemple, on a recours aux méthodes décrites dans
-@ref{Exemple : ajouter une articulation à plusieurs notes}, en
+@ref{Ajout d'articulation à des notes (exemple)}, en
particulier quant à l'emploi de @code{\displayMusic}.
@example
Certains réglages sont plus délicats que d'autres.
-@itemize @bullet
-
-
+@itemize
@item
-L'un d'entre eux est l'apparence des objets dits @qq{spanner}, qui
-s'étendent horizontalement, tels que les liaisons. Si, en principe, un
-seul de ces objets est créé à la fois et peut donc être modifié de façon
-habituelle, lorsque ces objets doivent enjamber un changement de ligne,
-ils sont dupliqués au début du ou des systèmes suivants. Comme ces
-objets sont des clones de l'objet d'origine, ils en héritent toutes les
-propriétés, y compris les éventuelles commandes @code{\override}.
-
+L'un d'entre eux est l'apparence des objets dits @qq{extenseurs}
+(@emph{spanner}), qui s'étendent horizontalement, tels que les liaisons.
+Si, en principe, un seul de ces objets est créé à la fois et peut donc
+être modifié de façon habituelle, lorsque ces objets doivent enjamber un
+changement de ligne, ils sont dupliqués au début du ou des systèmes
+suivants. Comme ces objets sont des clones de l'objet d'origine, ils en
+héritent toutes les propriétés, y compris les éventuelles commandes
+@code{\override}.
En d'autres termes, une commande @code{\override} affecte toujours les
-deux extrémités d'un objet @q{spanner}. Pour ne modifier que la partie
-précédant ou suivant le changement de ligne, il faut intervenir
+deux extrémités d'un objet @emph{spanner}. Pour ne modifier que la
+partie précédant ou suivant le changement de ligne, il faut intervenir
directement dans le processus de mise en page.
La fonction de rappel @code{after-line-breaking} contient toute
l'opération Scheme effectuée lorsque les sauts de lignes ont été
Dans l'exemple suivant, on définit une nouvelle opération nommée
@code{my-callback}. Cette opération
-@itemize @bullet
+@itemize
@item
détermine si l'objet a été divisé à l'occasion d'un changement de ligne
@item
-si oui, recherche les différents morceaux de l'objet
+dans l'affirmative, recherche les différents morceaux de l'objet
@item
vérifie si l'objet considéré est bien la deuxième moitié d'un objet
divisé
@item
-si oui, applique un espacement supplémentaire (@code{extra-offset}).
+dans l'affirmative, applique un espacement supplémentaire
+(@code{extra-offset}).
@end itemize
On ajoute cette procédure à l'objet @rinternals{Tie} (liaison de tenue),
@c KEEP LY
@lilypond[quote,verbatim,ragged-right]
#(define (my-callback grob)
- (let* (
- ; l'objet a-t-il été divisé ?
- (orig (ly:grob-original grob))
+ (let* (
+ ;; l'objet a-t-il été divisé ?
+ (orig (ly:grob-original grob))
- ; si oui, rechercher les morceaux frères (siblings)
- (siblings (if (ly:grob? orig)
- (ly:spanner-broken-into orig) '() )))
+ ;; si oui, rechercher les morceaux frères (siblings)
+ (siblings (if (ly:grob? orig)
+ (ly:spanner-broken-into orig)
+ '())))
- (if (and (>= (length siblings) 2)
- (eq? (car (last-pair siblings)) grob))
- (ly:grob-set-property! grob 'extra-offset '(-2 . 5)))))
+ (if (and (>= (length siblings) 2)
+ (eq? (car (last-pair siblings)) grob))
+ (ly:grob-set-property! grob 'extra-offset '(-2 . 5)))))
\relative c'' {
\override Tie #'after-line-breaking =
#my-callback
- c1 ~ \break c2 ~ c
+ c1 ~ \break
+ c2 ~ c
}
@end lilypond
@noindent
Lorsque cette astuce va être appliquée, notre nouvelle fonction de
rappel @code{after-line-breaking} devra également appeler celle
-d'origine (@code{after-line-breaking}), si elle existe.
-Ainsi, pour l'utiliser dans le cas d'un crescendo (objet
-@code{Hairpin}), il faudra appeler également
-@code{ly:spanner::kill-zero-spanned-time}.
+d'origine (@code{after-line-breaking}), si elle existe. Ainsi, pour
+l'utiliser dans le cas d'un crescendo (objet @code{Hairpin}), il faudra
+également appeler @code{ly:spanner::kill-zero-spanned-time}.
-@item Pour des raisons d'ordre technique, certains objets ne peuvent
-être modifiés par @code{\override}. Parmi ceux-là, les objets
+@item
+Pour des raisons d'ordre technique, certains objets ne peuvent être
+modifiés par @code{\override}. Parmi ceux-là, les objets
@code{NonMusicalPaperColumn} et @code{PaperColumn}. La commande
@code{\overrideProperty} sert à les modifier, de façon similaire à
-@code{\once \override}, mais avec une syntaxe différente@tie{}:
+@code{\once \override} mais avec une syntaxe différente@tie{}:
@example
\overrideProperty
#"Score.NonMusicalPaperColumn" % Nom de l'objet
#'line-break-system-details % Nom de la propriété
-#'((next-padding . 20)) % valeur
+#'((next-padding . 20)) % Valeur
@end example
-Notez cependant que la commande @code{\override} peut tout de même être
+Notez toutefois que la commande @code{\override} peut tout de même être
appliquée à @code{NonMusicalPaperColumn} et @code{PaperColumn} dans un
bloc @code{\context}.
@end itemize
+
+
+@node Interfaces LilyPond Scheme
+@chapter Interfaces LilyPond Scheme
+@translationof LilyPond Scheme interfaces
+
+@untranslated
+
--- /dev/null
+@c -*- coding: utf-8; mode: texinfo; documentlanguage: fr -*-
+
+@ignore
+ Translation of GIT committish: 3c62ac104645533873bba800f7b0f371089f535a
+
+ When revising a translation, copy the HEAD committish of the
+ version that you are working on. For details, see the Contributors'
+ Guide, node Updating translation committishes..
+@end ignore
+
+@c \version "2.15.20"
+
+@c Translators: Jean-Charles Malahieude
+
+@node Tutoriel Scheme
+@chapter Tutoriel Scheme
+
+@cindex Scheme
+@cindex GUILE
+@cindex Scheme, in-line code
+@cindex accessing Scheme
+@cindex evaluating Scheme
+@cindex LISP
+
+LilyPond recourt abondamment au langage de programmation Scheme, tant au
+niveau de la syntaxe de saisie que des mécanismes internes chargés de
+combiner les différents modules du logiciel. Les lignes qui suivent
+constituent un bref aperçu de la manière de saisir des données en
+Scheme. Si vous désirez en apprendre plus sur Scheme, n'hésitez pas à
+vous rendre sur @uref{http://@/www@/.schemers@/.org}.
+
+Le Scheme utilisé par LilyPond repose sur l'implémentation GNU
+Guile@tie{}; celle-ci se base sur le standard Scheme @qq{R5RS}. Si
+votre but est d'apprendre Scheme au travers de LilyPond, sachez que
+l'utilisation d'une autre implémentation ou d'un autre standard pourrait
+être source de désagrément. Vous trouverez plus d'information sur
+guile à la page @uref{http://www.gnu.org/software/guile/}@tie{}; le
+standard Scheme @qq{R5RS} est quant à lui disponible à la page
+@uref{http://www.schemers.org/Documents/Standards/R5RS/}.
+
+@menu
+* Introduction à Scheme::
+* Scheme et LilyPond::
+* Construction de fonctions complexes::
+@end menu
+
+
+@node Introduction à Scheme
+@section Introduction à Scheme
+@translationof Introduction to Scheme
+
+Nous commencerons par nous intéresser à Scheme et à son fonctionnement,
+grâce à l'interpréteur GUILE. Une fois plus à l'aise avec Scheme, nous
+verrons comment ce langage peut s'intégrer à un fichier LilyPond.
+
+@menu
+* Le bac à sable de Scheme::
+* Scheme et les variables::
+* Types de données Scheme simples::
+* Types de données Scheme composites::
+* Scheme et les calculs::
+* Scheme et les procédures::
+* Scheme et les conditions::
+@end menu
+
+
+@node Le bac à sable de Scheme
+@subsection Le bac à sable de Scheme
+@translationof Scheme sandbox
+
+L'installation de LilyPond comprend l'implémentation Guile de Scheme.
+La plupart des systèmes disposent d'un @qq{bac à sable} Scheme pour
+effectuer des tests@tie{}; vous y accéderez en tapant @qq{guile} dans
+un terminal. Certains systèmes, notamment Windows, nécessitent d'avoir
+auparavant créé la variable d'environnement @code{GUILE_LOAD_PATH} qui
+devra pointer vers le répertoire @code{../usr/share/guile/1.8} de
+l'installation de LilyPond -- pour connaître le chemin complet d'accès à
+ce répertoire, consultez @rlearning{Autres sources de documentation}.
+Les utilisateurs de Windows peuvent aussi prendre l'option @qq{Exécuter}
+à partir du menu @qq{Démarrer} puis taper @qq{guile}.
+
+Néanmoins, tous les paquetages de LilyPond disposent d'un bac à sable
+Scheme, accessible par la commande@tie{}:
+@example
+lilypond scheme-sandbox
+@end example
+
+@noindent
+Une fois le bac à sable actif, vous obtiendrez l'invite@tie{}:
+@lisp
+guile>
+@end lisp
+
+Vous pouvez dès à présent saisir des expressions Scheme pour vous
+exercer. Si vous souhaitez pourvoir utiliser la bibliothèque GNU
+@code{readline}, qui offre une ligne de commande plus élaborée,
+consultez les informations contenues dans le fichier
+@file{ly/scheme-sandbox.ly}. La bibliothèque @var{readline}, dans la
+mesure où elle est habituellement activée dans vos sessions Guile,
+devrait être effective y compris dans le bac à sable.
+
+
+@node Scheme et les variables
+@subsection Scheme et les variables
+@translationof Scheme variables
+
+Une variable Scheme peut contenir n'importe quelle valeur valide en
+Scheme, y compris une procédure Scheme.
+
+Une variable Scheme se crée avec la fonction @code{define}@tie{}:
+
+@lisp
+guile> (define a 2)
+guile>
+@end lisp
+
+L'évaluation d'une variable Scheme se réalise en saisissant le nom de
+cette variable à l'invite de Guile@tie{}:
+
+@lisp
+guile> a
+2
+guile>
+@end lisp
+
+Une variable Scheme s'affiche à l'écran à l'aide de la fonction
+@code{display}@tie{}:
+
+@lisp
+guile> (display a)
+2guile>
+@end lisp
+
+@noindent
+Vous aurez remarqué que la valeur @code{2} et l'invite @code{guile}
+apparaissent sur une même ligne. On peut améliorer la présentation à
+l'aide de la procédure @code{newline} ou bien en affichant un caractère
+@qq{retour chariot}.
+
+@lisp
+guile> (display a)(newline)
+2
+guile> (display a)(display "\n")
+2
+guile>
+@end lisp
+
+Après avoir créé une variable, vous pouvez en modifier la valeur grâce à
+un @code{set!}@tie{}:
+
+@lisp
+guile> (set! a 12345)
+guile> a
+12345
+guile>
+@end lisp
+
+Vous quitterez proprement le bac à sable à l'aide de l'instruction
+@code{quit}@tie{}:
+
+@lisp
+guile> (quit)
+@end lisp
+
+
+@node Types de données Scheme simples
+@subsection Types de données Scheme simples
+@translationof Scheme simple data types
+
+L'un des concepts de base de tout langage est la saisie de données,
+qu'il s'agisse de nombres, de chaînes de caractères, de listes etc.
+Voici les différents types de données Scheme simples utilisées
+couramment dans LilyPond.
+
+@table @asis
+@item Booléens
+Les valeurs booléennes sont vrai ou faux. En Scheme, ce sera @code{#t}
+pour vrai, et @code{#f} pour faux.
+@funindex ##t
+@funindex ##f
+
+@item Nombres
+Les nombres se saisissent le plus communément@tie{}: @code{1} est le
+nombre (entier) un, alors que @w{@code{-1.5}} est un nombre à virgule
+flottante (un nombre non entier).
+
+@item Chaînes
+Les chaînes de caractères sont bornées par des guillemets
+informatiques@tie{}:
+
+@example
+"ceci est une chaîne"
+@end example
+
+Une chaîne peut s'étendre su plusieurs lignes@tie{}:
+
+@example
+"ceci
+est
+une chaîne"
+@end example
+
+@noindent
+auquel cas les retours à la ligne seront inclus dans la chaîne.
+
+Un caractère de retour à la ligne peut s'ajouter dans la chaîne, sous la
+forme d'un @code{\n}.
+
+@example
+"ceci\nest une\nchaîne multiligne"
+@end example
+
+Guillemets et obliques inverses dans une chaîne doivent être précédés
+d'une oblique inverse. La chaîne @code{\a dit "b"} se saisit donc
+
+@example
+"\\a dit \"b\""
+@end example
+
+@end table
+
+Il existe bien d'autres types de donnée Scheme, dont nous ne parlerons
+pas ici. Vous en trouverez une liste exhaustive dans le guide de
+référence de Guile, à la page
+@uref{http://www.gnu.org/software/guile/manual/html_node/Simple-Data-Types.html}.
+
+
+@node Types de données Scheme composites
+@subsection Types de données Scheme composites
+@translationof Scheme compound data types
+
+Scheme prend aussi en charge des types de données composites. LilyPond
+utilise beaucoup les paires, listes, listes associatives et tables de
+hachage.
+
+@subheading Paires
+
+Le type de donnée composite fondamental est la paire (@code{pair}).
+Comme son nom l'indique, il s'agit de lier deux valeurs, à l'aide de
+l'opérateur @code{cons}.
+
+@lisp
+guile> (cons 4 5)
+(4 . 5)
+guile>
+@end lisp
+
+Vous aurez noté que la paire s'affiche sous la forme de deux éléments
+bornés par des parenthèses et séparés par une espace, un point
+(@code{.}) et une autre espace. Le point n'est en aucune manière un
+séparateur décimal@tie{}; il s'agit de l'indicateur d'une paire.
+
+Vous pouvez aussi saisir littéralement les valeurs d'une paire, en la
+faisant précéder d'une apostrophe.
+
+@lisp
+guile> '(4 . 5)
+(4 . 5)
+guile>
+@end lisp
+
+Les deux éléments d'une paire peuvent être constitués de n'importe
+quelle valeur Scheme valide@tie{}:
+
+@lisp
+guile> (cons #t #f)
+(#t . #f)
+guile> '("blah-blah" . 3.1415926535)
+("blah-blah" . 3.1415926535)
+guile>
+@end lisp
+
+Les premier et second éléments de la paire sont accessibles à l'aide des
+procédures Scheme @code{car} et @code{cdr}.
+
+@lisp
+guile> (define mypair (cons 123 "hello there")
+... )
+guile> (car mypair)
+123
+guile> (cdr mypair)
+"hello there"
+guile>
+@end lisp
+
+@noindent
+
+Note : @code{cdr} se prononce @qq{couldeur}, comme l'indiquent Sussman et
+Abelson -- voir
+@uref{http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-14.html#footnote_Temp_133}.
+
+
+@subheading Listes
+
+Autre structure de donnée commune en Scheme@tie{}: la liste
+(@emph{list}). Une liste se définit comme étant vide (représentée par
+@code{'()}) ou une paire dont le @code{cdr} est une liste.
+
+Il existe plusieurs méthodes pour créer une liste, la plus courante
+étant l'utilisation de la procédure @code{list}@tie{}:
+
+@lisp
+guile> (list 1 2 3 "abc" 17.5)
+(1 2 3 "abc" 17.5)
+@end lisp
+
+Comme vous le remarquez, une liste s'affiche sous la forme d'une suite
+d'éléments séparés par une espace, bornée par des parenthèses.
+Contrairement à une paire, il n'y a pas de point entre les éléments.
+
+Vous pouvez aussi saisir directement une liste en entourant ses éléments
+par des parenthèses à la suite d'une apostrophe@tie{}:
+
+@lisp
+guile> '(17 23 "foo" "bar" "bazzle")
+(17 23 "foo" "bar" "bazzle")
+@end lisp
+
+Les listes ont une importance considérable en Scheme. Certains vont
+d'ailleurs jusqu'à considérer Scheme comme un dialecte du lisp, où
+@qq{lisp} serait une abréviation de @qq{List Processing}. Il est vrai
+que toute expression Scheme est une liste.
+
+
+@subheading Listes associatives (alists)
+
+Il existe un type particulier de liste@tie{}: la @emph{liste
+associative} -- ou @emph{alist}. Une @emph{alist} permet de stocker des
+données dans le but de les réutiliser.
+
+Une liste associative est une liste dont les éléments sont des paires.
+Le @code{car} de chacun des éléments constitue une clé (@emph{key}) et
+chaque @code{cdr} une valeur (@emph{value}). La procédure Scheme
+@code{assoc} permet de retrouver une entrée de la liste
+associative@tie{}; son @code{cdr} en fournira la valeur@tie{}:
+
+@lisp
+guile> (define mon-alist '((1 . "A") (2 . "B") (3 . "C")))
+guile> mon-alist
+((1 . "A") (2 . "B") (3 . "C"))
+guile> (assoc 2 mon-alist)
+(2 . "B")
+guile> (cdr (assoc 2 mon-alist))
+"B"
+guile>
+@end lisp
+
+LilyPond recourt abondamment aux @emph{alists} pour stocker des
+propriétés ou autres données.
+
+
+@subheading Tables de hachage
+
+Il s'agit d'une structure de données à laquelle LilyPond fait parfois
+appel. Une table de hachage (@emph{hash table}) peut se comparer à une
+matrice ou un tableau dont l'index peut être n'importe quel type de
+valeur Scheme et ne se limitant pas à des nombres entiers.
+
+Les tables de hachage sont un moyen plus efficace que les listes
+associatives lorsqu'il s'agit d'enregistrer de nombreuses données qui ne
+changeront que peu fréquemment.
+
+La syntaxe permettant de créer une table de hachage peut paraître
+complexe, mais vous en trouverez de nombreux exemples dans les sources
+de LilyPond.
+
+@lisp
+guile> (define h (make-hash-table 10))
+guile> h
+#<hash-table 0/31>
+guile> (hashq-set! h 'cle1 "valeur1")
+"valeur1"
+guile> (hashq-set! h 'key2 "valeur2")
+"valeur2"
+guile> (hashq-set! h 3 "valeur3")
+"valeur3"
+@end lisp
+
+La procédure @code{hashq-ref} permet de récupérer une valeur dans la
+table de hachage.
+
+@lisp
+guile> (hashq-ref h 3)
+"valeur3"
+guile> (hashq-ref h 'cle2)
+"valeur2"
+guile>
+@end lisp
+
+La procédure @code{hashq-get-handle} permet de retrouver à la fois une
+clé et sa valeur. Cette procédure a l'avantage de renvoyer @code{#f}
+lorsque la clé n'existe pas.
+
+@lisp
+guile> (hashq-get-handle h 'cle1)
+(cle1 . "valeur1")
+guile> (hashq-get-handle h 'zut)
+#f
+guile>
+@end lisp
+
+@node Scheme et les calculs
+@subsection Scheme et les calculs
+@translationof Calculations in Scheme
+
+@ignore
+We have been using lists all along. A calculation, like @code{(+ 1 2)}
+is also a list (containing the symbol @code{+} and the numbers 1
+and@tie{}2). Normally lists are interpreted as calculations, and the
+Scheme interpreter substitutes the outcome of the calculation. To enter a
+list, we stop the evaluation. This is done by quoting the list with a
+quote @code{'} symbol. So, for calculations do not use a quote.
+
+Inside a quoted list or pair, there is no need to quote anymore. The
+following is a pair of symbols, a list of symbols and a list of lists
+respectively,
+
+@example
+#'(stem . head)
+#'(staff clef key-signature)
+#'((1) (2))
+@end example
+@end ignore
+
+Scheme permet aussi d'effectuer des calculs. Il utilise alors un
+@emph{préfixe}. Additionner 1 et@tie{}2 s'écrira @w{@code{(+ 1 2)}} et
+non @math{1+2} comme on aurait pu s'y attendre.
+
+@lisp
+guile> (+ 1 2)
+3
+@end lisp
+
+Les calculs peuvent s'imbriquer@tie{}; le résultat d'une fonction peut
+servir pour un autre calcul.
+
+@lisp
+guile> (+ 1 (* 3 4))
+13
+@end lisp
+
+Ces calculs sont un exemple d'évaluation@tie{}: une expression telle que
+@w{@code{(* 3 4)}} est remplacée par sa valeur, soit @code{12}.
+
+En matière de calcul, Scheme fait la différence entre des nombres entiers
+ou non. Les calculs sur des nombres entiers seront exacts, alors que
+s'il s'agit de nombres non entiers, les calculs tiendront compte de la
+précision mentionnée@tie{}:
+
+@lisp
+guile> (/ 7 3)
+7/3
+guile> (/ 7.0 3.0)
+2.33333333333333
+@end lisp
+
+Lorsque l'interpréteur Scheme rencontre une expression sous forme de
+liste, le premier élément de cette liste est considéré en tant que
+procédure qui prendra en argument le restant de la liste. C'est la
+raison pour laquelle, en Scheme, tous les opérateurs sont en préfixe.
+
+Le fait que le premier élément d'une expression Scheme sous forme de
+liste ne soit pas un opérateur ou une procédure déclenchera une
+erreur de la part de l'interpréteur@tie{}:
+
+@lisp
+guile> (1 2 3)
+
+Backtrace:
+In current input:
+ 52: 0* [1 2 3]
+
+<unnamed port>:52:1: In expression (1 2 3):
+<unnamed port>:52:1: Wrong type to apply: 1
+ABORT: (misc-error)
+guile>
+@end lisp
+
+Vous pouvez constater que l'interpréteur a tenté de considérer @code{1}
+comme étant un opérateur ou une procédure, ce qu'il n'a pu réaliser. Il
+a donc renvoyé l'erreur @qq{Wrong type to apply: 1} (@emph{Application
+d'un type erroné@tie{}: 1}).
+
+C'est pourquoi il est impératif, pour créer une liste, soit d'utiliser
+l'opérateur consacré (@code{list}), soit de faire précéder la liste
+d'une apostrophe, de telle sorte que l'interpréteur ne tente pas de
+l'évaluer.
+
+@lisp
+guile> (list 1 2 3)
+(1 2 3)
+guile> '(1 2 3)
+(1 2 3)
+guile>
+@end lisp
+
+Vous pourrez être confronté à cette erreur lorsque vous intégrerez
+Scheme à LilyPond.
+
+@ignore
+The same assignment can be done in completely in Scheme as well,
+
+@example
+#(define twentyFour (* 2 twelve))
+@end example
+
+@c this next section is confusing -- need to rewrite
+
+The @emph{name} of a variable is also an expression, similar to a
+number or a string. It is entered as
+
+@example
+#'twentyFour
+@end example
+
+@funindex #'symbol
+@cindex quoting in Scheme
+
+The quote mark @code{'} prevents the Scheme interpreter from substituting
+@code{24} for the @code{twentyFour}. Instead, we get the name
+@code{twentyFour}.
+@end ignore
+
+
+@node Scheme et les procédures
+@subsection Scheme et les procédures
+@translationof Scheme procedures
+
+Une procédure Scheme est une expression Scheme qui renverra une valeur
+issue de son exécution. Les procédures Scheme sont capables de
+manipuler des variables qui ne sont pas définies en leur sein.
+
+
+@subheading Définition de procédures
+
+En Scheme, on définit une procédure à l'aide de l'instruction
+@code{define}@tie{}:
+
+@example
+(define (nom-fonction argument1 argument2 ... argumentn)
+ expression-scheme-qui-donnera-une-valeur-en-retour)
+@end example
+
+Nous pourrions, par exemple, définir une procédure calculant la moyenne
+de deux nombres@tie{}:
+
+@lisp
+guile> (define (moyenne x y) (/ (+ x y) 2))
+guile> moyenne
+#<procedure moyenne (x y)>
+@end lisp
+
+Une fois la procédure définie, on l'appelle en la faisant suivre, dans
+une liste, des arguments qui doivent l'accompagner. Calculons
+maintenant la moyenne de 3 et 12@tie{}:
+
+@lisp
+guile> (moyenne 3 12)
+15/2
+@end lisp
+
+
+@subheading Prédicats
+
+Une procédure Scheme chargée de retourner une valeur booléenne s'appelle
+un @qq{prédicat} (@emph{predicate}). Par convention, plutôt que par
+nécessité, le nom d'un prédicat se termine par un point
+d'interrogation@tie{}:
+
+@lisp
+guile> (define (moins-de-dix? x) (< x 10))
+guile> (moins-de-dix? 9)
+#t
+guile> (moins-de-dix? 15)
+#f
+@end lisp
+
+
+@subheading Valeurs de retour
+
+Une procédure Scheme doit toujours renvoyer une valeur de retour, en
+l'occurrence la valeur de la dernière expression exécutée par cette
+procédure. La valeur de retour sera une valeur Scheme valide, y compris
+une structure de donnée complexe ou une procédure.
+
+On peut avoir besoin de regrouper plusieurs expressions Scheme dans une
+même procédure. Deux méthodes permettent de combiner des expressions
+multiples. La première consiste à utiliser la procédure @code{begin},
+qui permet l'évaluation de plusieurs expressions et renvoie la valeur de
+la dernière expression.
+
+@lisp
+guile> (begin (+ 1 2) (- 5 8) (* 2 2))
+4
+@end lisp
+
+Une deuxième méthode consiste à combiner les expressions dans un bloc
+@code{let}. Ceci aura pour effet de créer une série de liens, puis
+d'évaluer en séquence les expressions susceptibles d'inclure ces
+liens. La valeur renvoyée par un bloc @emph{let} est la valeur de
+retour de la dernière clause de ce bloc@tie{}:
+
+@lisp
+guile> (let ((x 2) (y 3) (z 4)) (display (+ x y)) (display (- z 4))
+... (+ (* x y) (/ z x)))
+508
+@end lisp
+
+
+@node Scheme et les conditions
+@subsection Scheme et les conditions
+@translationof Scheme conditionals
+
+@subheading if
+
+Scheme dispose d'une procédure @code{if}@tie{}:
+
+@example
+(if expression-test expression-affirmative expression-négative)
+@end example
+
+@var{expression-test} est une expression qui renverra une valeur
+booléenne. Dans le cas où @var{expression-test} retourne @code{#t}, la
+procédure @code{if} renvoie la valeur de @var{expression-affirmative},
+et celle de @var{expression-négative} dans le cas contraire.
+
+@lisp
+guile> (define a 3)
+guile> (define b 5)
+guile> (if (> a b) "a est plus grand que b" "a n'est pas plus grand que b")
+"a n'est pas plus grand que b"
+@end lisp
+
+
+@subheading cond
+
+Une autre manière d'introduire une condition en Scheme est d'utiliser
+l'instruction @code{cond}@tie{}:
+
+@example
+(cond (expression-test-1 expression-résultat-séquence-1)
+ (expression-test-2 expression-résultat-séquence-2)
+ ...
+ (expression-test-n expression-résultat-séquence-n))
+@end example
+
+Comme par exemple ici@tie{}:
+
+@lisp
+guile> (define a 6)
+guile> (define b 8)
+guile> (cond ((< a b) "a est plus petit que b")
+... ((= a b) "a égale b")
+... ((> a b) "a est plus grand que b"))
+"a est plus petit que b"
+@end lisp
+
+
+@node Scheme et LilyPond
+@section Scheme et LilyPond
+@translationof Scheme in LilyPond
+
+@menu
+* Syntaxe Scheme dans LilyPond::
+* Variables LilyPond::
+* Saisie de variables et Scheme::
+* Propriétés des objets::
+* Variables LilyPond composites::
+* Représentation interne de la musique::
+@end menu
+
+@node Syntaxe Scheme dans LilyPond
+@subsection Syntaxe Scheme dans LilyPond
+@translationof LilyPond Scheme syntax
+
+@funindex $
+@funindex #
+
+L'installation de LilyPond comprenant l'interpréteur Guile, les fichiers
+source LilyPond peuvent contenir du Scheme. Vous disposez de plusieurs
+méthodes pour inclure du Scheme dans vos fichiers LilyPond.
+
+La méthode la plus simple consiste à insérer un @emph{hash} (le caractère
+@code{#}, improprement appelé dièse) avant l'expression Scheme.
+
+Rappelons-nous qu'un fichier source LilyPond est structuré en jetons et
+expressions, tout comme le langage humain est structuré en mots et
+phrases. LilyPond dispose d'un analyseur lexical (appelé @emph{lexer})
+qui sait identifier les jetons -- nombres, chaînes, éléments Scheme,
+hauteurs etc. -- ainsi que d'un analyseur syntaxique (appelé
+@emph{parser}) -- voir l'annexe @ruser{Grammaire de LilyPond}. Dès lors
+que le programme sait quelle règle grammaticale particulière doit
+s'appliquer, il exécute les consignes qui lui sont associées.
+
+Le recours à un @emph{hash} pour mettre en exergue du Scheme est tout à
+fait approprié. Dès qu'il rencontre un @code{#}, l'analyseur lexical
+passe le relais au lecteur Scheme qui va alors déchiffrer l'intégralité
+de l'expression Scheme -- ce peut être un identificateur, une expression
+bornée par des parenthèses ou bien d'autres choses encore. Une fois
+cette expression lue, elle est enregistrée en tant que valeur d'un
+élément grammatical @code{SCM_TOKEN}. Puisque l'analyseur syntaxique
+sait comment traiter ce jeton, il charge Guile d'évaluer l'expression
+Scheme. Dans la mesure où le @emph{parser} requiert une lecture en
+avance de la part du @emph{lexer} pour prendre une décision, cette
+distinction entre lecture et évaluation -- @emph{lexer} et @emph{parser}
+-- révèle toute sa pertinence lorsqu'il s'agit d'exécuter conjointement
+des expressions LilyPond et des expressions Scheme. C'est la raison
+pour laquelle nous vous recommandons, dans toute la mesure du possible,
+d'utiliser un signe @emph{hash} lorsque vous faites appel à Scheme.
+
+Une autre manière de faire appel à l'interpréteur Scheme à partir de
+LilyPond consiste à introduire une expression Scheme par un caractère
+dollar au lieu d'un caractère dièse -- un@tie{}@code{$} au lieu
+d'un@tie{}@code{#}. En pareil cas, LilyPond évalue le code dès sa
+lecture par l'analyseur lexical, vérifie le type d'expression Scheme qui
+en résulte et détermine un type de jeton (l'un des @code{xxx_IDENTIFIER}
+de la grammaire) qui lui corresponde, puis en fait une copie qui servira
+à traiter la valeur de ce jeton. Lorsque la valeur de l'expression est
+@emph{void}, autrement dit une valeur Guile @code{*unspecified*}
+(pour @emph{non spécifiée}), aucune information n'est transmise à
+l'analyseur grammatical.
+
+C'est, en réalité, la manière dont LilyPond opère lorsque vous rappelez
+une variable ou une fonction par son nom -- au travers d'un @code{\nom}
+--, à la seule différence que sa finalité est déterminée par l'analyseur
+lexical de LilyPond sans consultation du lecteur Scheme@tie{}; le nom de
+la variable rappelée doit donc être en corrélation avec le mode LilyPond
+actif à ce moment là.
+
+L'immédiateté de l'opérateur @code{$} peut entraîner des effets
+indésirables dont nous reparlerons à la rubrique
+@ref{Saisie de variables et Scheme}@tie{}; aussi est-il préférable
+d'utiliser un @code{#} dès que l'analyseur grammatical le supporte.
+
+Examinons à présent du vrai code Scheme. Nous pouvons définir des
+procédures Scheme au milieu d'un fichier source LilyPond@tie{}:
+
+@example
+#(define (moyenne a b c) (/ (+ a b c) 3))
+@end example
+
+Pour mémoire, vous noterez que les commentaires LilyPond (@code{%} ou
+@code{%@{ %@}}) ne peuvent s'utiliser dans du code Scheme, même si
+celui-ci se trouve au sein d'un fichier LilyPond. Ceci tient au fait
+que l'expression Scheme est lue par l'interpréteur Guile, et en aucune
+façon par l'analyseur lexical de LilyPond. Voici comment introduire des
+commentaires dans votre code Scheme@tie{}:
+
+@example
+; ceci n'est qu'une simple ligne de commentaire
+
+#!
+ Ceci constitue un bloc de commentaire (non imbricable)
+ dans le style Guile.
+ En fait, les Schemeurs les utilisent très rarement,
+ et vous n'en trouverez jamais dans le code source
+ de LilyPond.
+!#
+@end example
+
+Dans la suite de notre propos, nous partons du principe que les données
+sont incluses dans un fichier musical, aussi toutes les expressions
+Scheme seront introduites par un@code{#}.
+
+Toutes les expressions Scheme de haut niveau incluses dans un fichier
+LilyPond peuvent se combiner en une expression Scheme unique à l'aide de
+la clause @code{begin}@tie{}:
+
+@example
+#(begin
+ (define foo 0)
+ (define bar 1))
+@end example
+
+
+@node Variables LilyPond
+@subsection Variables LilyPond
+@translationof LilyPond variables
+
+Les variables LilyPond sont enregistrées en interne sous la forme de
+variables Scheme. Ainsi,
+
+@example
+douze = 12
+@end example
+
+@noindent
+est équivalant à
+
+@example
+#(define douze 12)
+@end example
+
+Ceci a pour conséquence que toute variable LilyPond peut être utilisée
+dans une expression Scheme. Par exemple, nous pourrions dire
+
+@example
+vingtQuatre = #(* 2 douze)
+@end example
+
+@noindent
+ce qui aurait pour conséquence que le nombre 24 sera stocké dans la
+variable LilyPond (et Scheme) @code{vingtQuatre}.
+
+La façon habituelle de faire référence à une variable LilyPond consiste
+à la rappeler à l'aide d'une oblique inverse -- autrement dit saisir
+@code{\vingtQuatre}. Dans la mesure où ceci, pour la plupart des types
+internes de LilyPond y compris les expressions musicales, aura pour
+effet d'en recopier la valeur, les fonctions musicales n'ont pas pour
+habitude de créer une copie du matériau qu'elles vont modifier. De
+fait, une expression musicale introduite par @code{#} de devrait pas
+contenir de matériau inexistant auparavant ou bien littéralement
+recopié, mais plutôt une référence explicite.
+
+
+@node Saisie de variables et Scheme
+@subsection Saisie de variables et Scheme
+@translationof Input variables and Scheme
+
+Le format de saisie prend en charge la notion de variable -- ou
+identificateur. Dans l'exemple suivant, une expression musicale se voit
+attribuer un identificateur qui portera le nom de @code{traLaLa}.
+
+@example
+traLaLa = @{ c'4 d'4 @}
+@end example
+
+@noindent
+
+Une variable a aussi une portée. Dans l'exemple suivant, le bloc
+@code{\layout} contient une variable @code{traLaLa} tout à fait
+indépendante de l'autre @code{\traLaLa}.
+
+@example
+traLaLa = @{ c'4 d'4 @}
+\layout @{ traLaLa = 1.0 @}
+@end example
+
+Dans les faits, chaque fichier a un domaine de compétence, et les
+différents blocs @code{\header}, @code{\midi} et @code{\layout} ont leur
+propre champ de compétence, imbriqué dans ce domaine principal.
+
+Variables et champs de compétence sont implémentés par le système de
+modules de Guile. Un module anonyme Scheme est attaché à chacun de ces
+domaines. Une assertion telle que
+
+@example
+traLaLa = @{ c'4 d'4 @}
+@end example
+
+@noindent
+est convertie, en interne, en une définition Scheme@tie{}:
+
+@example
+(define traLaLa @var{valeur Scheme de `@code{... }'})
+@end example
+
+Cela signifie que variables LilyPond et variables Scheme peuvent tout à
+fait se mélanger. Dans l'exemple suivant, un fragment musical est
+stocké dans la variable @code{traLaLa} puis dupliqué à l'aide de Scheme.
+Le résultat est alors importé dans un bloc @code{\score} au moyen d'une
+seconde variable @code{twice}.
+
+@lilypond[verbatim]
+traLaLa = { c'4 d'4 }
+
+#(define newLa (map ly:music-deep-copy
+ (list traLaLa traLaLa)))
+#(define twice
+ (make-sequential-music newLa))
+
+{ \twice }
+@end lilypond
+
+@c Due to parser lookahead
+
+Cet exemple est particulièrement intéressant. L'assignation
+n'interviendra qu'une fois que l'analyseur grammatical aura l'assurance
+que rien du type de @code{\addlyrics} ne suit@tie{}; il doit donc
+vérifier ce qui vient après. Le @emph{parser} lit le @code{#} et
+l'expression Scheme qui le suit @strong{sans} l'évaluer, de telle sorte
+qu'il peut procéder à l'assignation, et @strong{ensuite} exécuter le
+code Scheme sans problème.
+
+Cet exemple illustre la manière @qq{d'exporter} une expression musicale
+à partir des saisies et à destination de l'interpréteur Scheme.
+L'inverse est aussi réalisable@tie{}: en la plaçant derrière
+un@tie{}@code{$}, une valeur Scheme sera interprétée comme si elle avait
+été saisie en syntaxe LilyPond. Au lieu de définir @code{\twice}, nous
+aurions tout aussi bien pu écrire
+
+@example
+...
+@{ $(make-sequential-music (list newLa)) @}
+@end example
+
+Vous pouvez utiliser @code{$} suivi d'une expression Scheme partout où
+vous auriez utilisé @code{\@var{nom}}, dès lors que vous aurez assigné à
+cette expression Scheme le nom de variable @var{nom}. La substitution
+intervenant au niveau de l'analyseur lexical (le @emph{lexer}), LilyPond
+ne saurait faire la différence.
+
+Cette manière de procéder comporte cependant un inconvénient au niveau
+de la temporisation. Si nous avions défini @code{newLa} avec un
+@code{$} plutôt qu'un@tie{#}, la définition Scheme suivante aurait
+échoué du fait que @code{traLaLa} n'était pas encore définie. Pour plus
+d'information quant au problème de synchronisation, voir la rubrique
+@ref{Syntaxe Scheme dans LilyPond}.
+
+En tout état de cause, le @emph{parser} évalue le code Scheme en
+dernier. S'il ne doit être exécuté que plus tard, consultez la rubrique
+@ref{Fonctions Scheme fantômes}, ou stockez le dans une macro comme
+ici@tie{}:
+
+@example
+#(define (nopc)
+ (ly:set-option 'point-and-click #f))
+
+...
+#(nopc)
+@{ c'4 @}
+@end example
+
+@knownissues
+L'imbrication de variables Scheme et LilyPond n'est pas possible
+avec l'option @option{--safe}.
+
+
+@node Propriétés des objets
+@subsection Propriétés des objets
+@translationof Object properties
+
+Les propriétés des objets sont stockées dans LilyPond sous la forme
+d'enchaînements de listes associatives, autrement dit des listes de
+listes associatives. Une propriété se détermine par l'ajout de valeurs
+en début de liste de cette propriété. Les caractéristiques d'une
+propriété s'ajustent donc à la lecture des différentes valeurs des
+listes associatives.
+
+La modification d'une valeur pour une propriété donnée requiert
+l'assignation d'une valeur de la liste associative, tant pour la clé que
+la valeur associée. Voici comment procéder selon la syntaxe de
+LilyPond@tie{}:
+
+@example
+\override Stem #'thickness = #2.6
+@end example
+
+Cette instruction ajuste l'apparence des hampes. Une entrée
+@w{@code{'(thickness . 2.6)}} de la @emph{alist} est ajoutée à la liste
+de la propriété de l'objet @code{Stem}. @code{thickness} devant
+s'exprimer en unité d'épaisseur de ligne, les hampes auront donc une
+épaisseur de 2,6@tie{}ligne de portée, et à peu près le double de leur
+épaisseur normale. Afin de faire la distinction entre les variables que
+vous définissez au fil de vos fichiers -- tel le @code{vingtQuatre} que
+nous avons vu plus haut -- et les variables internes des objets, nous
+parlerons de @qq{propriétés} pour ces dernières, et de @qq{variables}
+pour les autres. Ainsi, l'objet hampe possède une propriété
+@code{thickness}, alors que @code{vingtQuatre} est une variable.
+
+@cindex propriétés ou variables
+@cindex variables ou propriétés
+
+@c todo -- here we're getting interesting. We're now introducing
+@c LilyPond variable types. I think this deserves a section all
+@c its own
+
+
+@node Variables LilyPond composites
+@subsection Variables LilyPond composites
+@translationof LilyPond compound variables
+
+@subheading Décalages (@emph{offsets})
+
+Les décalages (@emph{offset}) sur deux axes (coordonnées X et Y) sont
+stockés sous forme de @emph{paires}. Le @code{car} de l'offset
+correspond à l'abscisse (coordonnée X) et le @code{cdr} à l'ordonnée
+(coordonnée Y).
+
+@example
+\override TextScript #'extra-offset = #'(1 . 2)
+@end example
+
+Cette clause affecte la paire @code{(1 . 2)} à la propriété
+@code{extra-offset} de l'objet @code{TextScript}. Ces nombres sont
+exprimés en espace de portée. La commande aura donc pour effet de
+déplacer l'objet d'un espace de portée vers la droite, et de deux
+espaces vers le haut.
+
+Les procédures permettant de manipuler les offsets sont regroupées dans
+le fichier @file{scm/lily-library.scm}.
+
+
+@subheading Fractions
+
+Les fractions, tel que LilyPond les utilise, sont aussi stockées sous
+forme de @emph{paire}. Alors que Scheme est tout à fait capable de
+représenter des nombres rationnels, vous conviendrez que, musicalement
+parlant, @samp{2/4} et @samp{1/2} ne se valent pas@tie{}; nous devrons
+donc pouvoir les distinguer. Dans le même ordre d'idée, LilyPond ne
+connaît pas les @qq{fractions} négatives. Pour ces raisons, @code{2/4}
+en LilyPond correspond à @code{(2 . 4)} en Scheme, et @code{#2/4} en
+LilyPond correspond à @code{1/2} en Scheme.
+
+
+@subheading Étendues (@emph{extents})
+
+Les paires permettent aussi de stocker des intervalles qui représentent
+un ensemble de nombres compris entre un minimum (le @code{car}) et un
+maximum (le @code{cdr}). Ces intervalles stockent l'étendue, tant au
+niveau horizontal (X) que vertical (Y) des objets imprimables. En
+matière d'étendue sur les X, le @code{car} correspond à la coordonnée de
+l'extrémité gauche, et le @code{cdr} à la coordonnée de l'extrémité
+droite. En matière d'étendue sur les Y, le @code{car} correspond à la
+coordonnée de l'extrémité basse, et le @code{cdr} à la coordonnée de
+l'extrémité haute.
+
+Les procédures permettant de manipuler les offsets sont regroupées dans
+le fichier @file{scm/lily-library.scm}. Nous vous recommandons
+l'utilisation de ces procédures dans toute la mesure du possible afin
+d'assurer la cohérence du code.
+
+
+@subheading Propriété en @emph{alists}
+
+Les propriétés en @emph{alists} sont des structures de données
+particulières à LilyPond. Il s'agit de listes associatives dont les
+clés sont des propriétés et les valeurs des expressions Scheme
+fournissant la valeur requise pour cette propriété.
+
+Les propriétés LilyPond sont des symboles Scheme, à l'instar de
+@code{'thickness}.
+
+
+@subheading Chaînes d'@emph{alist}
+
+Une chaîne d'@emph{alist} est une liste contenant les listes
+associatives d'une propriété.
+
+L'intégralité du jeu de propriétés qui doivent s'appliquer à un objet
+graphique est en fait stocké en tant que chaîne d'@emph{alist}. Afin
+d'obtenir la valeur d'une propriété particulière qu'un objet graphique
+devrait avoir, on examinera chacune des listes associatives de la
+chaîne, à la recherche d'une entrée contenant la clé de cette propriété.
+Est renvoyée la première entrée d'@emph{alist} trouvée, sa valeur étant
+la valeur de la propriété.
+
+L'obtention des valeurs de propriété des objets graphiques se réalise en
+principe à l'aide de la procédure Scheme @code{chain-assoc-get}.
+
+
+@node Représentation interne de la musique
+@subsection Représentation interne de la musique
+@translationof Internal music representation
+
+Dans les entrailles du programme, la musique se présente comme une liste
+Scheme. Cette liste comporte les différents éléments qui affecteront la
+sortie imprimable. L'analyse grammaticale (l'opération @emph{parsing})
+est le processus chargé de convertir la musique représentée par le code
+LilyPond en présentation interne Scheme.
+
+L'analyse d'une expression musicale se traduit par un jeu d'objets
+musicaux en Scheme. Une objet musical est déterminé par le temps qu'il
+occupe, que l'on appelle @emph{durée}. Les durées s'expriment par des
+nombres rationnels représentant la longueur d'un objet musical par
+rapport à la ronde.
+
+Un objet musical dispose de trois types@tie{}:
+@itemize
+@item
+un nom de musique@tie{}: Toute expression musicale a un nom. Par
+exemple, une note amène à un @rinternals{NoteEvent}, un
+@code{\simultaneous} à un @rinternals{SimultaneousMusic}. Une liste
+exhaustive des différentes expressions est disponible dans la référence
+des propriétés internes, à la rubrique @rinternals{Music expressions}.
+
+@item
+un @qq{type} ou interface@tie{}: Tout nom de musique dispose de
+plusieurs types ou interfaces. Ainsi, une note est tout à la fois un
+@code{event}, un @code{note-event}, un @code{rhythmic-event} et un
+@code{melodic-event}. Les différentes classes musicales sont
+répertoriées à la rubrique @rinternals{Music classes} de la référence
+des propriétés internes.
+
+@item
+un objet C++@tie{}: Tout objet musical est représenté par un objet de la
+classe C++ @code{Music}.
+@end itemize
+
+L'information réelle d'une expression musicale est enregistrée sous
+forme de propriétés. Par exemple, un @rinternals{NoteEvent} dispose des
+propriétés @code{pitch} et @code{duration}, respectivement chargées de
+stocker la hauteur et la durée de cette note. Les différentes
+propriétés sont répertoriées à la rubrique
+@rinternalsnamed{Music properties,Music properties}
+de la référence des propriétés internes.
+
+Une expression composite est un objet musical dont les propriétés
+contiennent d'autres objets musicaux. S'il s'agit d'une liste d'objets,
+elle sera stockée dans la propriété @code{elements} d'un objet
+musical@tie{}; s'il n'y a qu'un seul objet @qq{enfant}, il sera stocké
+dans la propriété @code{element}. Ainsi, par exemple, les enfants de
+@rinternals{SequentialMusic} iront dans @code{elements}, alors que
+l'argument unique de @rinternals{GraceMusic} ira dans @code{element}.
+De même, le corps d'une répétition ira dans la propriété @code{element}
+d'un @rinternals{RepeatedMusic}, les alternatives quant à elles dans la
+propriété @code{elements}.
+
+
+@node Construction de fonctions complexes
+@section Construction de fonctions complexes
+@translationof Building complicated functions
+
+Nous allons voir dans cette partie les moyens dont vous disposez pour
+obtenir les informations qui vous permettront de créer vos propres
+fonctions musicales complexes.
+
+@menu
+* Affichage d'expressions musicales::
+* Propriétés musicales::
+* Doublement d'une note avec liaison (exemple)::
+* Ajout d'articulation à des notes (exemple)::
+@end menu
+
+
+@node Affichage d'expressions musicales
+@subsection Affichage d'expressions musicales
+@translationof Displaying music expressions
+
+@cindex stockage interne
+@cindex expression musicale, affichage
+@cindex représentation interne, affichage
+@cindex displayMusic
+@funindex \displayMusic
+
+Lorsque l'on veut écrire une fonction musicale, il est intéressant
+d'examiner comment une expression musicale est représentée en interne.
+Vous disposez à cet effet de la fonction musicale @code{\displayMusic}.
+
+@example
+@{
+ \displayMusic @{ c'4\f @}
+@}
+@end example
+
+@noindent
+affichera
+
+@example
+(make-music
+ 'SequentialMusic
+ 'elements
+ (list (make-music
+ 'NoteEvent
+ 'articulations
+ (list (make-music
+ 'AbsoluteDynamicEvent
+ 'text
+ "f"))
+ 'duration
+ (ly:make-duration 2 0 1 1)
+ 'pitch
+ (ly:make-pitch 0 0 0))))
+@end example
+
+Par défaut, LilyPond affichera ces messages sur la console, parmi toutes
+les autres informations. Vous pouvez, afin de les isoler et de garder
+le résultat des commandes @code{\display@{TRUC@}}, rediriger la sortie
+vers un fichier@tie{}:
+
+@example
+lilypond file.ly >display.txt
+@end example
+
+Un peu de Scheme combiné à notre code LilyPond, et les seules
+informations qui nous intéressent se retrouveront directement dans un
+fichier indépendant@tie{}:
+
+@example
+@{
+ $(with-output-to-file "display.txt"
+ (lambda () #@{ \displayMusic @{ c'4\f @} #@}))
+@}
+@end example
+
+L'information sera encore plus lisible après un peu de mise en
+forme@tie{}:
+
+@example
+(make-music 'SequentialMusic
+ 'elements (list
+ (make-music 'NoteEvent
+ 'articulations (list
+ (make-music 'AbsoluteDynamicEvent
+ 'text
+ "f"))
+ 'duration (ly:make-duration 2 0 1 1)
+ 'pitch (ly:make-pitch 0 0 0))))
+@end example
+
+Une séquence musicale @code{@{ ... @}} se voit attribuer le nom de
+@code{SequentialMusic}, et les expressions qu'elle contient sont
+enregistrées en tant que liste dans sa propriété @code{'elements}. Une
+note est représentée par un objet @code{NoteEvent} -- contenant les
+propriétés de durée et hauteur -- ainsi que l'information qui lui est
+attachée -- en l'occurrence un @code{AbsoluteDynamicEvent} ayant une
+propriété @code{text} de valeur @code{"f"} -- et stockée dans sa
+propriété @code{articulations}.
+
+@funindex{\void}
+La fonction @code{\displayMusic} renvoie la musique qu'elle
+affiche@tie{}; celle-ci sera donc aussi interprétée. L'insertion d'une
+commande @code{\void} avant le @code{\displayMusic} permet de
+s'affranchir de la phase d'interprétation.
+
+
+@node Propriétés musicales
+@subsection Propriétés musicales
+@translationof Music properties
+
+Nous abordons ici les propriétés @emph{music}, et non pas les propriétés
+@emph{context} ou @emph{layout}.
+
+Partons de cet exemple simple@tie{}:
+
+@example
+someNote = c'
+\displayMusic \someNote
+===>
+(make-music
+ 'NoteEvent
+ 'duration
+ (ly:make-duration 2 0 1 1)
+ 'pitch
+ (ly:make-pitch 0 0 0))
+@end example
+
+L'objet @code{NoteEvent} est la représentation brute de @code{someNote}.
+Voyons ce qui se passe lorsque nous plaçons ce @notation{c'} dans une
+construction d'accord@tie{}:
+
+@example
+someNote = <c'>
+\displayMusic \someNote
+===>
+(make-music
+ 'EventChord
+ 'elements
+ (list (make-music
+ 'NoteEvent
+ 'duration
+ (ly:make-duration 2 0 1 1)
+ 'pitch
+ (ly:make-pitch 0 0 0))))
+@end example
+
+L'objet @code{NoteEvent} est maintenant le premier objet de la propriété
+@code{'elements} de @code{someNote}.
+
+@code{\displayMusic} utilise la fonction @code{display-scheme-music}
+pour afficher la représentation en Scheme d'une expression musicale@tie{}:
+
+@example
+#(display-scheme-music (first (ly:music-property someNote 'elements)))
+===>
+(make-music
+ 'NoteEvent
+ 'duration
+ (ly:make-duration 2 0 1 1)
+ 'pitch
+ (ly:make-pitch 0 0 0))
+@end example
+
+La hauteur de la note est accessible au travers de la propriété
+@code{'pitch} de l'objet @code{NoteEvent}@tie{}:
+
+@example
+#(display-scheme-music
+ (ly:music-property (first (ly:music-property someNote 'elements))
+ 'pitch))
+===>
+(ly:make-pitch 0 0 0)
+@end example
+
+La hauteur de la note se modifie en définissant sa propriété
+@code{'pitch}@tie{}:
+
+@funindex \displayLilyMusic
+
+@example
+#(set! (ly:music-property (first (ly:music-property someNote 'elements))
+ 'pitch)
+ (ly:make-pitch 0 1 0)) ;; set the pitch to d'.
+\displayLilyMusic \someNote
+===>
+d'
+@end example
+
+
+@node Doublement d'une note avec liaison (exemple)
+@subsection Doublement d'une note avec liaison (exemple)
+@translationof Doubling a note with slurs (example)
+
+Supposons que nous ayons besoin de créer une fonction transformant une
+saisie @code{a} en @w{@code{@{ a( a) @}}}. Commençons par examiner
+comment le résultat est représenté en interne.
+
+@example
+\displayMusic@{ a'( a') @}
+===>
+(make-music
+ 'SequentialMusic
+ 'elements
+ (list (make-music
+ 'NoteEvent
+ 'articulations
+ (list (make-music
+ 'SlurEvent
+ 'span-direction
+ -1))
+ 'duration
+ (ly:make-duration 2 0 1 1)
+ 'pitch
+ (ly:make-pitch 0 5 0))
+ (make-music
+ 'NoteEvent
+ 'articulations
+ (list (make-music
+ 'SlurEvent
+ 'span-direction
+ 1))
+ 'duration
+ (ly:make-duration 2 0 1 1)
+ 'pitch
+ (ly:make-pitch 0 5 0))))
+@end example
+
+Mauvaise nouvelle@tie{}! Les expressions @code{SlurEvent} doivent
+s'ajouter @qq{à l'intérieur} de la note -- dans sa propriété
+@code{articulations}.
+
+Examinons à présent la saisie@tie{}:
+
+@example
+\displayMusic a'
+===>
+(make-music
+ 'NoteEvent
+ 'duration
+ (ly:make-duration 2 0 1 1)
+ 'pitch
+ (ly:make-pitch 0 5 0))))
+@end example
+
+Nous aurons donc besoin, dans notre fonction, de cloner cette expression
+-- de telle sorte que les deux notes constituent la séquence -- puis
+d'ajouter un @code{SlurEvent} à la propriété @code{'articulations} de
+chacune d'elles, et enfin réaliser un @code{SequentialMusic} de ces deux
+@code{EventChords}. En tenant compte du fait que, dans le cadre d'un
+ajout, une propriété non définie est lue @code{'()} (une liste vide),
+aucune vérification n'est requise avant d'introduire un nouvel élément
+en tête de la propriété @code{articulations}.
+
+@example
+doubleSlur = #(define-music-function (parser location note) (ly:music?)
+ "Renvoie : @{ note ( note ) @}.
+ `note' est censé être une note unique."
+ (let ((note2 (ly:music-deep-copy note)))
+ (set! (ly:music-property note 'articulations)
+ (cons (make-music 'SlurEvent 'span-direction -1)
+ (ly:music-property note 'articulations)))
+ (set! (ly:music-property note2 'articulations)
+ (cons (make-music 'SlurEvent 'span-direction 1)
+ (ly:music-property note2 'articulations)))
+ (make-music 'SequentialMusic 'elements (list note note2))))
+@end example
+
+
+@node Ajout d'articulation à des notes (exemple)
+@subsection Ajout d'articulation à des notes (exemple)
+@translationof Adding articulation to notes (example)
+
+Le moyen d'ajouter une articulation à des notes consiste à fusionner
+deux expressions musicales en un même contexte, comme nous l'avons vu à
+la rubrique @ruser{Création d'un contexte}. L'option de réaliser
+nous-mêmes une fonction musicale à cette fin nous offre l'avantage de
+pouvoir alors ajouter une articulation, telle qu'une instruction de
+doigté, individuellement à l'une des notes d'un accord, ce qui est
+impossible dans le cadre d'une simple fusion de musique indépendante.
+
+Un @code{$variable} au milieu de la notation @code{#@{...#@}} se
+comporte exactement comme un banal @code{\variable} en notation LilyPond
+traditionnelle. Nous savons déjà que
+
+@example
+@{ \musique -. -> @}
+@end example
+
+@noindent
+n'est pas admis par LilyPond. Nous pourrions tout à fait contourner ce
+problème en attachant l'articulation à une @qq{fausse} note,
+
+@example
+@{ << \musique s1*0-.-> @}
+@end example
+
+@noindent
+mais, pour les besoins de la démonstration, nous allons voir comment
+réaliser ceci en Scheme. Commençons par examiner une saisie simple et
+le résultat auquel nous désirons aboutir@tie{}:
+
+@example
+% saisie
+\displayMusic c4
+===>
+(make-music
+ 'NoteEvent
+ 'duration
+ (ly:make-duration 2 0 1 1)
+ 'pitch
+ (ly:make-pitch -1 0 0))))
+=====
+% résultat attendu
+\displayMusic c4->
+===>
+(make-music
+ 'NoteEvent
+ 'articulations
+ (list (make-music
+ 'ArticulationEvent
+ 'articulation-type
+ "accent"))
+ 'duration
+ (ly:make-duration 2 0 1 1)
+ 'pitch
+ (ly:make-pitch -1 0 0))
+@end example
+
+Nous voyons qu'une note (@code{c4}) est représentée par une expression
+@code{NoteEvent}. Si nous souhaitons ajouter une articulation
+@notation{accent}, nous devrons ajouter une expression
+@code{ArticulationEvent} à la propriété @code{articulations} de
+l'expression @code{NoteEvent}.
+
+Construisons notre fonction en commençant par
+
+@example
+(define (ajoute-accent note-event)
+ "Ajoute un accent (ArticulationEvent) aux articulations de `note-event',
+ qui est censé être une expression NoteEvent."
+ (set! (ly:music-property note-event 'articulations)
+ (cons (make-music 'ArticulationEvent
+ 'articulation-type "accent")
+ (ly:music-property note-event 'articulations)))
+ note-event)
+@end example
+
+La première ligne est la manière de définir une fonction en
+Scheme@tie{}: la fonction Scheme a pour nom @code{ajoute-accent} et elle
+comporte une variable appelée @code{note-event}. En Scheme, le type
+d'une variable se déduit la plupart de temps de par son nom -- c'est
+d'ailleurs une excellente pratique que l'on retrouve dans de nombreux
+autres langages.
+
+@example
+"Ajoute un accent..."
+@end example
+
+@noindent
+décrit ce que fait la fonction. Bien que ceci ne soit pas primordial,
+tout comme des noms de variable évidents, tâchons néanmoins de prendre
+de bonnes habitudes dès nos premiers pas.
+
+Vous pouvez vous demander pourquoi nous modifions directement
+l'événement note plutôt que d'en manipuler une copie -- on pourrait
+utiliser @code{ly:music-deep-copy} à cette fin. La raison en est qu'il
+existe un contrat tacite@tie{}: les fonctions musicales sont autorisées
+à modifier leurs arguments -- ils sont générés en partant de zéro (comme
+les notes que vous saisissez) ou déjà recopiés (faire référence à une
+variable musicale avec @samp{\name} ou à de la musique issue
+d'expressions Scheme @samp{$(@dots{})} aboutit à une copie). Dans la
+mesure où surmultiplier les copies serait contre productif, la valeur de
+retour d'une fonction musicale n'est @strong{pas} recopiée. Afin de
+respecter ce contrat, n'utilisez pas un même argument à plusieurs
+reprises, et n'oubliez pas que le retourner compte pour une utilisation.
+
+Dans un exemple précédent, nous avons construit de la musique en
+répétant un certain argument musical. Dans ce cas là, l'une des
+répétitions se devait d'être une copie. Dans le cas contraire,
+certaines bizarreries auraient pu survenir. Par exemple, la présence
+d'un @code{\relative} ou d'un @code{\transpose}, après plusieurs
+répétitions du même élément, entraînerait des @qq{relativisations} ou
+transpositions en cascade. Si nous les assignons à une variable
+musicale, l'enchaînement est rompu puisque la référence à @samp{\nom}
+créera une nouvelle copie sans toutefois prendre en considération
+l'identité des éléments répétés.
+
+Cette fonction n'étant pas une fonction musicale à part entière, elle
+peut s'utiliser dans d'autres fonctions musicales. Il est donc sensé de
+respecter le même contrat que pour les fonctions musicales@tie{}:
+l'entrée peut être modifiée pour arriver à une sortie, et il est de la
+responsabilité de l'appelant d'effectuer des copies s'il a réellement
+besoin de l'argument dans son état originel. Vous constaterez, à la
+lecture des fonctions propres à LilyPond, comme @code{music-map}, que ce
+principe est toujours respecté.
+
+Revenons à nos moutons@dots{} Nous disposons maintenant d'un
+@code{note-event} que nous pouvons modifier, non pas grâce à un
+@code{ly:music-deep-copy}, mais plutôt en raison de notre précédente
+réflexion. Nous ajoutons @notation{l'accent} à la liste de ses
+propriétés @code{'articulations}.
+
+@example
+(set! emplacement nouvelle-valeur)
+@end example
+
+L'emplacement est ce que nous voulons ici définir. Il s'agit de la
+propriété @code{'articulations} de l'expression @code{note-event}.
+
+@example
+(ly:music-property note-event 'articulations)
+@end example
+
+La fonction @code{ly:music-property} permet d'accéder aux propriétés
+musicales -- les @code{'articulations}, @code{'duration}, @code{'pitch}
+etc. que @code{\displayMusic} nous a indiquées. La nouvelle valeur sera
+l'ancienne propriété @code{'articulations}, augmentée d'un
+élément@tie{}: l'expression @code{ArticulationEvent}, que nous
+recopions à partir des informations de @code{\displayMusic}.
+
+@example
+(cons (make-music 'ArticulationEvent
+ 'articulation-type "accent")
+ (ly:music-property result-event-chord 'articulations))
+@end example
+
+@code{cons} permet d'ajouter un élément en tête de liste sans pour
+autant modifier la liste originale. C'est exactement ce que nous
+recherchons@tie{}: la même liste qu'auparavant, plus la nouvelle
+expression @code{ArticulationEvent}. L'ordre au sein de la propriété
+@code{'articulations} n'a ici aucune importance.
+
+Enfin, après avoir ajouté l'articulation @notation{accent} à sa
+propriété @code{articulations}, nous pouvons renvoyer le
+@code{note-event}, ce que réalise la dernière ligne de notre fonction.
+
+Nous pouvons à présent transformer la fonction @code{ajoute-accent} en
+fonction musicale, à l'aide d'un peu d'enrobage syntaxique et mention du
+type de son unique argument @qq{réel}.
+
+@example
+ajouteAccent = #(define-music-function (parser location note-event)
+ (ly:music?)
+ "Ajoute un accent (ArticulationEvent) aux articulations de `note-event',
+ qui est censé être une expression NoteEvent."
+ (set! (ly:music-property note-event 'articulations)
+ (cons (make-music 'ArticulationEvent
+ 'articulation-type "accent")
+ (ly:music-property note-event 'articulations)))
+ note-event)
+@end example
+
+Par acquis de conscience, vérifions que tout ceci fonctione@tie{}:
+
+@example
+\displayMusic \ajouteAccent c4
+@end example
+
+
+
+
+
+@ignore
+@menu
+* Tweaking with Scheme::
+@end menu
+
+@c @nod e Tweaking with Scheme
+@c @sectio n Tweaking with Scheme
+
+We have seen how LilyPond output can be heavily modified using
+commands like
+@code{\override TextScript #'extra-offset = ( 1 . -1)}. But
+we have even more power if we use Scheme. For a full explanation
+of this, see the @ref{Scheme tutorial}, and
+@ref{Interfaces for programmers}.
+
+We can use Scheme to simply @code{\override} commands,
+
+TODO Find a simple example
+@c This isn't a valid example with skylining
+@c It works fine without padText -td
+@end ignore
+
+@ignore
+@lilypond[quote,verbatim,ragged-right]
+padText = #(define-music-function (parser location padding) (number?)
+#{
+ \once \override TextScript #'padding = #padding
+#})
+
+\relative c''' {
+ c4^"piu mosso" b a b
+ \padText #1.8
+ c4^"piu mosso" d e f
+ \padText #2.6
+ c4^"piu mosso" fis a g
+}
+@end lilypond
+@end ignore
+
+@ignore
+We can use it to create new commands:
+
+@c Check this is a valid example with skylining
+@c It is - 'padding still works
+
+
+@lilypond[quote,verbatim,ragged-right]
+tempoPadded = #(define-music-function (parser location padding tempotext)
+ (number? string?)
+#{
+ \once \override Score.MetronomeMark #'padding = $padding
+ \tempo \markup { \bold #tempotext }
+#})
+
+\relative c'' {
+ \tempo \markup { "Low tempo" }
+ c4 d e f g1
+ \tempoPadded #4.0 #"High tempo"
+ g4 f e d c1
+}
+@end lilypond
+
+
+Even music expressions can be passed in:
+
+@lilypond[quote,verbatim,ragged-right]
+pattern = #(define-music-function (parser location x y) (ly:music? ly:music?)
+#{
+ $x e8 a b $y b a e
+#})
+
+\relative c''{
+ \pattern c8 c8\f
+ \pattern {d16 dis} { ais16-> b\p }
+}
+@end lilypond
+@end ignore