]> git.donarmstrong.com Git - lilypond.git/commitdiff
Doc-fr: enable Extending
authorJean-Charles Malahieude <lilyfan@orange.fr>
Tue, 6 Mar 2012 16:14:41 +0000 (17:14 +0100)
committerJean-Charles Malahieude <lilyfan@orange.fr>
Tue, 6 Mar 2012 16:14:41 +0000 (17:14 +0100)
  * master file
  * Scheme tutorial (first delivery)
  * programming interface (re-enable old material & update skeleton)

Documentation/fr/extending.tely [new file with mode: 0644]
Documentation/fr/extending/programming-interface.itely
Documentation/fr/extending/scheme-tutorial.itely [new file with mode: 0644]

diff --git a/Documentation/fr/extending.tely b/Documentation/fr/extending.tely
new file mode 100644 (file)
index 0000000..346c0e6
--- /dev/null
@@ -0,0 +1,78 @@
+\input texinfo @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
+
+@setfilename lilypond-extending.info
+@settitle GNU LilyPond -- Extension des fonctionnalités
+@documentencoding UTF-8
+@documentlanguage fr
+@afourpaper
+
+@c Translators: Jean-Charles Malahieude
+
+@macro manualIntro
+Ce document constitue fournit les informations de base pour étendre les
+fonctionnalités de LilyPond@tie{}version @version{}.
+@end macro
+
+@c `Extending' was born 2003-04-23 with git commit c08f6e8...
+@macro copyrightDeclare
+Copyright @copyright{} 2003--2012 by par les auteurs.
+@end macro
+
+@set FDL
+@include macros.itexi
+
+
+@c don't remove this comment.
+@ignore
+@omfcreator Han-Wen Nienhuys, Jan Nieuwenhuizen and Graham Percival
+@omfdescription Programming extensions for the LilyPond music engraving system
+@omftype program usage
+@omfcategory Applications|Publishing
+@omflanguage English
+@end ignore
+
+
+@lilyTitlePage{Extension des fonctionnalités}
+
+
+@c TOC -- non-tex
+@ifnottex
+
+@menu
+* Tutoriel Scheme::              Programmation dans LilyPond.
+* Interfaces pour programmeurs:: Comment dialoguer avec scheme.
+* Interfaces LilyPond Scheme::   Obtention d'information dans la musique et autour
+
+Appendices
+
+* GNU Free Documentation License:: Licence de ce document.
+* Index de LilyPond::
+@end menu
+
+@docMain
+@end ifnottex
+
+
+@contents
+
+@allowcodebreaks false
+
+@include extending/scheme-tutorial.itely
+@include extending/programming-interface.itely
+
+@include fdl.itexi
+
+@node Index de LilyPond
+@appendix Index de LilyPond
+@translationof LilyPond index
+
+@printindex cp
+
+@bye
index 13901180e5829b41d06ff12cfea624c509a10078..53767027b23d4ca33d6a9542388c613913e7ed3d 100644 (file)
 @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.
@@ -269,7 +309,7 @@ symboles @samp{^} ou @samp{_}.
 
 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
@@ -301,22 +341,20 @@ finale de @samp{m} lui-même.
 
 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é
@@ -326,16 +364,17 @@ systèmes différents.
 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),
@@ -345,49 +384,59 @@ rehaussé.
 @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
+
diff --git a/Documentation/fr/extending/scheme-tutorial.itely b/Documentation/fr/extending/scheme-tutorial.itely
new file mode 100644 (file)
index 0000000..7e43a19
--- /dev/null
@@ -0,0 +1,1649 @@
+@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