gen-unicode-data.py 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. import regex
  2. def get_matches(regex_expr):
  3. regex_expr_compiled = regex.compile(regex_expr)
  4. unicode_ranges = []
  5. current_range = None
  6. for codepoint in range(0x110000):
  7. char = chr(codepoint)
  8. if regex_expr_compiled.match(char):
  9. if current_range is None:
  10. current_range = [codepoint, codepoint]
  11. else:
  12. current_range[1] = codepoint
  13. elif current_range is not None:
  14. unicode_ranges.append(tuple(current_range))
  15. current_range = None
  16. if current_range is not None:
  17. unicode_ranges.append(tuple(current_range))
  18. return unicode_ranges
  19. def print_cat(mode, cat, ranges):
  20. if mode == "range":
  21. print("const std::vector<std::pair<uint32_t, uint32_t>> unicode_ranges_{} = {{".format(cat)) # noqa: NP100
  22. if mode == "map":
  23. print("const std::map<uint32_t, uint32_t> unicode_map_{} = {{".format(cat)) # noqa: NP100
  24. for i, values in enumerate(ranges):
  25. end = ",\n" if (i % 4 == 3 or i + 1 == len(ranges)) else ", "
  26. values = ["0x%08X" % value for value in values]
  27. print("{" + ", ".join(values) + "}", end=end) # noqa: NP100
  28. print("};") # noqa: NP100
  29. print("") # noqa: NP100
  30. print_cat("range", "number", get_matches(r'\p{N}'))
  31. print_cat("range", "letter", get_matches(r'\p{L}'))
  32. print_cat("range", "separator", get_matches(r'\p{Z}'))
  33. print_cat("range", "accent_mark", get_matches(r'\p{M}'))
  34. print_cat("range", "punctuation", get_matches(r'\p{P}'))
  35. print_cat("range", "symbol", get_matches(r'\p{S}'))
  36. print_cat("range", "control", get_matches(r'\p{C}'))
  37. print_cat("range", "whitespace", get_matches(r'\s'))
  38. map_lowercase = []
  39. map_uppercase = []
  40. for codepoint in range(0x110000):
  41. char = chr(codepoint)
  42. lower = ord(char.lower()[0])
  43. upper = ord(char.upper()[0])
  44. if codepoint != lower:
  45. map_lowercase.append((codepoint, lower))
  46. if codepoint != upper:
  47. map_uppercase.append((codepoint, upper))
  48. print_cat("map", "lowercase", map_lowercase)
  49. print_cat("map", "uppercase", map_uppercase)
  50. # TODO: generate unicode_map_nfd