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 1.8KB

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