Conteneurs requalifiants
------------------------

Unpure-pure containers

Les conteneurs requalifiants permettent de faciliter le calcul des espacements en cas de modification du Y-axis -- plus particulièrement les composantes Y-offset et Y-extent -- à l'aide d'une fonction scheme en lieu et place de valeurs.

Unpure-pure containers are useful for overriding Y-axis spacing calculations - specifically Y-offset and Y-extent - with a Scheme function instead of a literal (i.e. a number or pair).

L'envergure verticale (Y-extent) de certains objets dépend de la propriété stencil ; jouer sur leur stencil requiert alors une intervention supplémentaire au niveau du Y-extent à l'aide d'un conteneur transitoire.  Lorsq'une fonction affecte un Y-offset ou un Y-extent, cela déclenche la détermination des sauts de ligne de manière anticipée dans la séquence des traitements.  Il en résulte que cette opération n'est en fait pas exécutée ; elle renvoie habituellement 0 ou '(0 . 0), ce qui peut engendrer des collisions.  Une fonction pure évitera d'avorter la construction des propriétés ou objets, qui de ce fait verront leurs arguments liés à la verticalité (Y-axis) correctement évalués.

For certain grobs, the Y-extent is based on the stencil property, overriding the stencil property of one of these will require an additional Y-extent override with an unpure-pure container.  When a function overrides a Y-offset and/or Y-extent it is assumed that this will trigger line breaking calculations too early during compilation.  So the function is not evaluated at all (usually returning a value of 0 or '(0 . 0)) which can result in collisions.  A pure function will not affect properties, objects or grob suicides and therefore will always have its Y-axis-related evaluated correctly.

Il existe actuellement une trentaine de fonctions que l'on peut qualifier de pures.  Le recours à un conteneur transitoire permet de requalifier une fonction de telle sorte qu'elle soit reconnue comme pure et soit donc évaluée avant détermination des sauts de ligne -- l'espacement horizontal sera de fait ajusté en temps et en heure. La fonction impure sera ensuite évaluée après le positionnement des sauts de ligne.

Currently, there are about thirty functions that are already considered pure and Unpure-pure containers are a way to set functions not on this list as pure.  The pure function is evaluated before any line-breaking and so the horizontal spacing can be adjusted in time.  The unpure function is then evaluated after line breaking.

Il n'est pas toujours facile d'avoir l'assurance qu'une fonction soit qualifiée de pure ; aussi nous vous recommandons d'éviter d'utiliser les objets Beam or VerticalAlignment lorsque vous désirez en créer une.

As it is difficult to always know which functions are on this list we recommend that any pure functions you create do not use Beam or VerticalAlignment grobs.

Un conteneur requalifiant se construit selon la syntaxe An unpure-pure container is constructed as follows;

(ly:make-unpure-pure-container f0 f1)

où f0 est une fonction prenant N arguments (N >= 1), le premier devant être l'objet en question ; il s'agit de la fonction dont le résultat sera réutilisé.  F1 est la fonction qui sera qualifée de pure.  Elle prend N + 2 arguments, le premier devant être lui aussi l'objet en question, et les second et troisième étant respectivement les point de départ (START) et point d'arrivée (END).

where f0 is a function taking N arguments (N >= 1) and the first argument must always be the grob.  This is the function that gives the actual result.  F1 is the function being labeled as pure that takes N + 2 arguments.  Again, the first argument must always still be the grob but the second and third are start and end arguments.

START et END sont dans tous les cas des valeurs fictives qui trouveront leur utilité dans le cas d'obets de type Spanners, tels les soufflets (Hairpin) ou barres de ligature (Beam), en retournant les différentes estimations de hauteur basées sur leurs début et fin d'extension.

START and END are, for all intents and purposes, dummy values that only matter for Spanners (i.e Hairpin or Beam), that can return different height estimations based on a starting and ending column.

Viennent ensuite les autres arguments de la fonction initiale f0 -- autrement dit aucun si N = 1.

The rest are the other arguments to the first function (which may be none if N = 1).

Les résultats de la deuxième fonction (f1) permettent une valeur approximative qui sera ensuite utilisée par la fonction initiale aux fins d'ajustement lors des phases ultérieures d'espacement.

The results of the second function are used as an approximation of the value needed which is then used by the first function to get the real value which is then used for fine-tuning much later during the spacing process.

[verbatim,quote,ragged-right]
#(define (square-line-circle-space grob)
(let* ((pitch (ly:event-property (ly:grob-property grob 'cause) 'pitch))
(notename (ly:pitch-notename pitch)))
(if (= 0 (modulo notename 2))
(make-circle-stencil 0.5 0.0 #t)
(make-filled-box-stencil '(0 . 1.0)
'(-0.5 . 0.5)))))

squareLineCircleSpace =
\override NoteHead #'stencil = #square-line-circle-space

smartSquareLineCircleSpace =
\squareLineCircleSpace
\override NoteHead #'Y-extent =
#(ly:make-unpure-pure-container
ly:grob::stencil-height
(lambda (grob start end) (ly:grob::stencil-height grob)))

\new Voice \with  \remove "Stem_engraver"
\relative c''
\squareLineCircleSpace
cis4 ces cisis c
\smartSquareLineCircleSpace
cis4 ces cisis c

La première mesure de l'exemple ci-dessus ne fait pas appel à un conteneur requalifiant, le moteur d'espacement n'a donc aucune connaissance de la largeur des têtes de note et ne peut empêcher qu'elles ne chevauchent les altérations.  Dans la deuxième mesure, par contre, le recours à un conteneur requalifiant informe le moteur d'espacement de la largeur des têtes de note ; les collisions sont alors évitées du fait de l'espace réservé à chacune des têtes.

In the first measure, without the unpure-pure container, the spacing engine does not know the width of the note head and lets it collide with the accidentals.  In the second measure, with unpure-pure containers, the spacing engine knows the width of the note heads and avoids the collision by lengthening the line accordingly.

Lorsqu'il s'agit de calculs simples, les fonctions, tant pour la partie pure que pour la partie impure, peuvent être identiques au détail près du nombre d'arguments utilisés ou du domaiane d'intervention.

Usually for simple calculations nearly-identical functions for both the unpure and pure parts can be used, by only changing the number of arguments passed to, and the scope of, the function.

Le fait de qualifier une fonction de pure alors qu'elle ne l'est pas peut générer des résultats imprévisibles.

If a function is labeled as pure and it turns out not to be, the results can be unexpected.