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; } }