Deltas

Le delta est une description technique des différences, c'est-à-dire une description pouvant être traitée par la machine en vue de produire un résultat, typiquement un nouveau document (patch, merge) ou bien une forme différentielle. Chaque opération du delta précise l'action à effectuer (insertion, suppression...) ainsi que la localisation de cette action (numéro de ligne, de caractère...).

Soit le delta suivant décrivant les différences entre les fichiers v1.txt et v2.txt de la section précédente :

1
<delta>
2
    <removeLine index="2"/>
3
    <insertLine afterIndex="1">Un décompte de 30 secondes s'enclenche alors dans l'onglet "Administration avancée".</insertLine>
4
    <insertLine afterIndex="2">Les utilisateurs reçoivent le message dans l'interface de l'application.</insertLine>
5
</delta>

Ce delta utilise deux types d'opération, insertLine et removeLine. L'attribut afterLine dans la balise insertLine précise l'index de la ligne après laquelle la nouvelle ligne a été ajoutée, dont le contenu est spécifié à l'intérieur de la balise. L'attribut lineIndex dans la balise removeLine indique l'index de la ligne supprimée. Notons que le contenu de la ligne supprimée n'est pas nécessaire dans le delta, puisqu'il s'agit d'un contenu présent dans la version à laquelle le delta va être appliqué (v1).

Pour obtenir v2 à partir de v1 à l'aide d'un patch, les opérations du delta doivent être effectuées dans l'ordre prescrit. Par exemple, si les deux premières opérations sont inversées, ce sera la ligne venant juste d'être insérée ("Un décompte de 30 secondes...") qui sera supprimée, et non la ligne 2 de v1 ("Les utilisateurs le reçoivent alors...") qui aura été décalée à la ligne 3 par l'insertion. D'autres ordonnancements de ces opérations sont possibles en revanche (le delta n'est pas unique), cependant les index des lignes concernées ne seront pas les mêmes, tel que dans le delta suivant :

1
<delta>
2
    <insertLine afterIndex="2">Un décompte de 30 secondes s'enclenche alors dans l'onglet "Administration avancée".</insertLine>
3
    <removeLine index="2"/>
4
    <insertLine afterIndex="2">Les utilisateurs reçoivent le message dans l'interface de l'application.</insertLine>
5
</delta>

Ces deux deltas peuvent aussi être utilisés pour construire la première forme différentielle que nous avons proposée. L'application du delta sur v1 consiste à insérer les lignes de v2 et à formater les lignes pour l'affichage des différences, par exemple de la manière suivante :

1
<p>Pour envoyer un message de maintenance aux utilisateurs connectés, sélectionnez le message adapté dans la liste déroulante, puis cliquez sur "Envoyer".</p>
2
<p><del>Les utilisateurs le reçoivent alors dans l'interface de l'application pendant 30 secondes.</del></p>
3
<p><ins>Un décompte de 30 secondes s'enclenche alors dans l'onglet "Administration avancée".</ins></p>
4
<p><ins>Les utilisateurs reçoivent le message dans l'interface de l'application.</ins></p>
5
<p>Si, avant la fin du décompte, aucun utilisateur ne s'oppose à l'opération de maintenance, le message "Aucun utilisateur ne s'oppose à l'opération de maintenance" s'affiche.</p>

Notons que les opérations de type removeLine ne doivent pas mener à la suppression pure et simple de la ligne, contrairement à la logique d'un patch. Ainsi dans notre exemple, la ligne 2 dans la forme différentielle reste bien la ligne 2 de v1. Pour que les opérations suivantes ne soient pas faussées, le programme doit pouvoir réévaluer dynamiquement chaque index en lui ajoutant le nombre de suppressions qui n'auront pas "réellement eu lieu" aux index inférieurs ou égaux à cet index. Par exemple dans le deuxième delta ci-dessus, la dernière insertion devra avoir lieu après la troisième ligne, et non pas la deuxième.

Opérations atomiques et opérations complexes

Barabucci (2013[1]) propose un modèle de delta générique dans lequel il distingue deux types d'opération : atomiques et complexes. Les opérations atomiques sont les opérations qui ne peuvent pas être composées à partir d'autres opérations. Il s'agit typiquement des opérations d'insertion et de suppression, telles que nous les avons utilisées dans les deux deltas ci-dessus. Dans le cadre d'un patch par exemple, ces opérations sont suffisantes. Les opérations complexes sont quant à elles des opérations composées à partir d'opérations atomiques. Dans l'exemple de la seconde forme différentielle, les opérations d'insertion et de suppression ne suffisent pas (du moins, pas directement) pour afficher les différences en face à face : il faut pour cela une indication explicite du remplacement de la seconde ligne de v1 par les seconde et troisième lignes de v2, afin d'opposer ces deux groupes de lignes dans un tableau par exemple. Le remplacement pouvant être obtenu à partir d'un ensemble d'insertions et de suppressions localisées à des index adjacents, il constitue une opération complexe que l'on peut mobiliser dans le delta (ici, pour la seconde forme différentielle) :

1
<delta>
2
	<replaceLines index="2" length="1">
3
		<line>Un décompte de 30 secondes s'enclenche alors dans l'onglet "Administration avancée".</line>
4
		<line>Les utilisateurs reçoivent le message dans l'interface de l'application.</line>
5
	</replaceLines>
6
</delta>

Concernant les deux dernières formes différentielles, un deuxième niveau d'expression des différences entre en jeu, celui des caractères. Les opérations basiques sont ici removeChars et insertChars (nous préférons le terme "basique" ici, car les opérations atomiques sont plus logiquement l'insertion et la suppression d'un seul caractère). Les index représentent une position de caractère dans la chaîne (notons que pour chaque opération, l'index prend en compte le nombre de caractères supprimés et ajoutés lors des opérations précédentes). Les balises removeChars possèdent également un attribut indiquant la longueur de la sous-chaîne à supprimer. Dans le delta ci-dessous, nous utilisons également l'opération complexe updateLine, pouvant être composée à partir des opérations removeChars et insertChars à condition, par exemple, que le volume de ces différences de caractères par rapport à la longueur moyenne des deux lignes ne soit pas trop important (dans le cas contraire, ces deux lignes sont "trop différentes" et gagnent à être exprimées dans un couple insertLine/removeLine).

1
<delta>
2
    <insertLine afterIndex="1">Un décompte de 30 secondes s'enclenche alors dans l'onglet "Administration avancée".</insertLine>
3
    <updateLine index="3">
4
        <removeChars index="17" length="3"/>
5
        <removeChars index="27" length="6"/>
6
        <insertChars afterIndex="27"> le message</insertChars>
7
        <removeChars index="72" length="20"/>
8
    </updateLine>
9
</delta>