Repository with sources and generator of https://larlet.fr/david/ https://larlet.fr/david/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

typography.py 2.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import regex # pour le support de "\p{}"
  2. # ESPACE_FINE_INSECABLE = unicodedata.lookup("NARROW NO-BREAK SPACE")
  3. # ESPACE_INSECABLE = unicodedata.lookup("NO-BREAK SPACE")
  4. # Pour distinguer dans le HTML produit plus facilement.
  5. ESPACE_FINE_INSECABLE = " "
  6. ESPACE_INSECABLE = " "
  7. def assemble_regexes(*regexes):
  8. return "|".join(regexes)
  9. def build_regex(avant, apres):
  10. # \p{} permet de reconnaître un caractère par sa catégorie Unicode
  11. # "Zs" est la catégorie "Separator, space".
  12. return (
  13. rf"((?P<avant>{avant})"
  14. + rf"(\p{{Zs}}|{ESPACE_INSECABLE})"
  15. + rf"(?P<apres>{apres}))"
  16. )
  17. RE_ESPACE_FINE_INSECABLE = regex.compile(
  18. assemble_regexes(
  19. build_regex(r"\w?", r"[;\?!]"), # Ponctuations doubles.
  20. build_regex(r"\d", r"([ghj]|min|mg|L|km|°C)(\b|$)"), # Unités.
  21. build_regex(r"\d", r"(Mo|Ko|Go|Mb|Kb|Gb)(\b|$)"), # Tailles de fichiers.
  22. build_regex(r"\d", r"%"), # Pourcentages.
  23. build_regex(r"\d", r"€"), # Symboles monétaires.
  24. build_regex(r"\d", r"\d"), # Séparateurs de milliers.
  25. )
  26. )
  27. def insere_espaces_fines_insecables(texte):
  28. return RE_ESPACE_FINE_INSECABLE.sub(
  29. r"\g<avant>" + ESPACE_FINE_INSECABLE + r"\g<apres>", texte
  30. )
  31. RE_ESPACE_INSECABLE = regex.compile(
  32. assemble_regexes(
  33. build_regex(r"\w?", r":"), # Deux points.
  34. build_regex(r"«", r"\w?"), # Guillemets en chevrons.
  35. # "Po" est la catégorie "Punctuation, other".
  36. build_regex(r"[\w\p{Po}]?", r"»"), # Guillemets en chevrons.
  37. build_regex(r"\d", r"(?!\d)\w"), # Chiffre suivi de lettres.
  38. build_regex(r"(M\.|Mme)", r"\w"), # Titres (Monsieur, Madame).
  39. )
  40. )
  41. def insere_espaces_insecables(texte):
  42. return RE_ESPACE_INSECABLE.sub(
  43. r"\g<avant>" + ESPACE_INSECABLE + r"\g<apres>", texte
  44. )
  45. def typographie(texte):
  46. """
  47. Utilise les espaces insécables fines ou normales lorsque c’est approprié
  48. https://fr.wikipedia.org/wiki/Espace_ins%C3%A9cable#En_France
  49. """
  50. return insere_espaces_fines_insecables(insere_espaces_insecables(texte))