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

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  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(
  21. r"\d", r"([ghj]|min|sec|images|mm|hab|mg|L|km|°C|GHz)(\b|$)"
  22. ), # Unités.
  23. build_regex(r"\d", r"(Mo|Ko|Go|Mb|Kb|Gb)(\b|$)"), # Tailles de fichiers.
  24. build_regex(r"\d", r"%"), # Pourcentages.
  25. build_regex(r"\d", r"€"), # Symboles monétaires.
  26. build_regex(r"\d", r"\d"), # Séparateurs de milliers.
  27. )
  28. )
  29. def insere_espaces_fines_insecables(texte):
  30. return RE_ESPACE_FINE_INSECABLE.sub(
  31. r"\g<avant>" + ESPACE_FINE_INSECABLE + r"\g<apres>", texte
  32. )
  33. RE_ESPACE_INSECABLE = regex.compile(
  34. assemble_regexes(
  35. build_regex(r"\w?", r":"), # Deux points.
  36. build_regex(r"«", r"\w?"), # Guillemets en chevrons.
  37. # "Po" est la catégorie "Punctuation, other".
  38. build_regex(r"[\w\p{Po}]?", r"»"), # Guillemets en chevrons.
  39. build_regex(r"\d", r"(?!\d)\w"), # Chiffre suivi de lettres.
  40. build_regex(r"(M\.|Mme)", r"\w"), # Titres (Monsieur, Madame).
  41. )
  42. )
  43. def insere_espaces_insecables(texte):
  44. return RE_ESPACE_INSECABLE.sub(
  45. r"\g<avant>" + ESPACE_INSECABLE + r"\g<apres>", texte
  46. )
  47. def typographie(texte):
  48. """
  49. Utilise les espaces insécables fines ou normales lorsque c’est approprié
  50. https://fr.wikipedia.org/wiki/Espace_ins%C3%A9cable#En_France
  51. """
  52. return insere_espaces_fines_insecables(insere_espaces_insecables(texte))