Couper le role BnF meme quand le prenom finit par une initiale

NettoyageIsbd.Auteur("Cormen, Thomas H. Auteur du texte") renvoyait
« Thomas H. Auteur du texte Cormen » : le point de l initiale etait
protege, donc plus aucun point ne servait de separateur de role.

Ce qui tranche : dans « Nom, Prenom », la seule chose qui puisse suivre
une initiale et faire encore partie du nom est une autre initiale
(« Tolkien, J. R. R. »). Tout le reste est le role. Le point est conserve
quand il clot une initiale, pour ne pas amputer le prenom.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
mathieu
2026-08-18 02:43:07 +02:00
co-authored by Claude Opus 5
parent 9cb3ca535d
commit 0fde244d0b
2 changed files with 45 additions and 22 deletions
+34 -16
View File
@@ -128,7 +128,9 @@ public static partial class NettoyageIsbd
var pointRole = IndexDuPointDeRole(s);
if (pointRole >= 0)
{
s = s[..pointRole];
// Quand le rôle suit une initiale (« Cormen, Thomas H. Auteur du texte »), le point
// qui sert de séparateur appartient aussi au nom : on le conserve.
s = EstPointDInitiale(s, pointRole) ? s[..(pointRole + 1)] : s[..pointRole];
}
s = RetirerPonctuationFinale(s);
@@ -174,12 +176,7 @@ public static partial class NettoyageIsbd
while (s.EndsWith('.'))
{
var i = s.Length - 1;
var estInitiale = i >= 1
&& char.IsUpper(s[i - 1])
&& (i == 1 || s[i - 2] == ' ' || s[i - 2] == '-' || s[i - 2] == '\'');
if (estInitiale)
if (EstPointDInitiale(s, s.Length - 1))
{
break;
}
@@ -194,9 +191,15 @@ public static partial class NettoyageIsbd
/// Position du point qui introduit le rôle, ou -1.
/// </summary>
/// <remarks>
/// Un point suivi d'une espace sépare le rôle du nom. On ignore les points d'initiales
/// (« Cormen, Thomas H. Auteur ») : un point précédé d'une majuscule isolée n'est pas
/// un séparateur de rôle.
/// Un point suivi d'une espace sépare le rôle du nom. Le point d'une initiale
/// (« Cormen, Thomas <b>H.</b> ») n'en est pas un — le couper amputerait le prénom.
/// <para>
/// Mais protéger l'initiale ne doit pas protéger le rôle qui la suit : « Cormen, Thomas H.
/// Auteur du texte » renvoyait auparavant « Thomas H. Auteur du texte Cormen ». Ce qui
/// tranche : dans « Nom, Prénom », la seule chose qui puisse suivre une initiale et faire
/// encore partie du nom est <b>une autre initiale</b> (« Tolkien, J. R. R. »). Tout le
/// reste est le rôle.
/// </para>
/// </remarks>
private static int IndexDuPointDeRole(string s)
{
@@ -207,16 +210,31 @@ public static partial class NettoyageIsbd
continue;
}
var estInitiale = i >= 1
&& char.IsUpper(s[i - 1])
&& (i == 1 || s[i - 2] == ' ' || s[i - 2] == '-' || s[i - 2] == '\'');
if (!estInitiale)
if (EstPointDInitiale(s, i) && CommenceParUneInitiale(s, i + 2))
{
return i;
continue;
}
return i;
}
return -1;
}
/// <summary>
/// Le point en <paramref name="i"/> clôt-il une initiale (majuscule isolée) ?
/// </summary>
private static bool EstPointDInitiale(string s, int i)
=> i >= 1
&& char.IsUpper(s[i - 1])
&& (i == 1 || s[i - 2] == ' ' || s[i - 2] == '-' || s[i - 2] == '\'');
/// <summary>
/// Le texte à partir de <paramref name="debut"/> commence-t-il par une initiale
/// (une majuscule suivie d'un point ou de la fin de chaîne) ?
/// </summary>
private static bool CommenceParUneInitiale(string s, int debut)
=> debut < s.Length
&& char.IsUpper(s[debut])
&& (debut + 1 == s.Length || s[debut + 1] == '.');
}