namespace MaBibli.Shared.Textes;
///
/// Clé d'identification d'une œuvre à partir d'un titre, indépendamment de l'édition.
///
///
/// C'est le rapprochement le moins mauvais dont on dispose, et il faut être clair sur ses limites.
///
/// Pourquoi pas l'ISBN ? Parce qu'il désigne une édition, pas une œuvre : le poche
/// de 1998, le grand format de 1991 et la réédition de 2015 portent trois ISBN différents pour le
/// même roman. Mesuré sur la bibliographie BnF de Bernard Werber : 183 notices de livres pour
/// 51 œuvres, chacune revenant en moyenne trois fois sous trois ISBN. Comparer les ISBN
/// répondrait donc « vous ne l'avez pas » à propos d'un livre posé sur l'étagère, ce qui est le
/// pire résultat possible pour une liste d'envies.
///
///
/// Ce que la clé fait. Elle coupe la mention de responsabilité ISBD (« / ») puis
/// le sous-titre (« : »), et met le reste à plat. C'est ce qui réunit
/// « Les thanatonautes », « Les thanatonautes : roman » et
/// « Les thanatonautes / Bernard Werber ».
///
///
/// Ce qu'elle rate, et qu'il ne faut pas prétendre autrement :
///
/// - Deux œuvres distinctes partageant un titre principal sont confondues (« Œuvres »,
/// « Nouvelles »). Le risque est borné : la comparaison n'a lieu qu'à auteur donné.
/// - Un tome n'est pas rapproché de son recueil : « Troisième humanité » et
/// « Troisième humanité. Tome 1 » restent deux lignes. Le point n'est pas coupé, faute de savoir
/// distinguer « Tome 1 » d'un titre qui contient légitimement un point.
/// - Un titre retraduit ou changé au fil des rééditions n'est pas rapproché du tout.
/// - Une œuvre possédée à l'intérieur d'une intégrale n'est pas repérée : l'intégrale a son
/// propre titre.
///
/// Conséquence assumée : l'écran de bibliographie peut afficher comme « à découvrir » un livre
/// déjà présent sous un autre titre. Il ne fait donc que griser ce qu'il reconnaît, sans
/// jamais masquer une ligne — un faux négatif se voit et se corrige d'un coup d'œil, alors qu'une
/// ligne masquée à tort serait invisible.
///
///
public static class CleOeuvre
{
/// Sépare le titre de la mention de responsabilité : « Germinal / Émile Zola ».
private const string SeparateurResponsabilite = " / ";
/// Sépare le titre de son sous-titre : « Les thanatonautes : roman ».
private const string SeparateurSousTitre = " : ";
///
/// Clé comparable d'un titre : « Les thanatonautes : roman » → les thanatonautes.
///
public static string Cle(string? titre)
{
var s = titre?.Trim();
if (string.IsNullOrEmpty(s))
{
return string.Empty;
}
s = Tronquer(s, SeparateurResponsabilite);
var sansSousTitre = Tronquer(s, SeparateurSousTitre);
// Un titre qui n'est QUE son sous-titre (« : roman ») ne doit pas se réduire à rien :
// mieux vaut alors garder la chaîne entière que produire une clé vide, qui se
// confondrait avec toutes les autres clés vides.
var retenu = NormalisationTexte.Normaliser(sansSousTitre);
return retenu.Length > 0 ? retenu : NormalisationTexte.Normaliser(s);
}
private static string Tronquer(string s, string separateur)
{
var i = s.IndexOf(separateur, StringComparison.Ordinal);
return i >= 0 ? s[..i].Trim() : s;
}
}