tex.py 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. from __future__ import annotations
  2. import re
  3. from manimlib.utils.tex_to_symbol_count import TEX_TO_SYMBOL_COUNT
  4. def num_tex_symbols(tex: str) -> int:
  5. """
  6. This function attempts to estimate the number of symbols that
  7. a given string of tex would produce.
  8. Warning, it may not behave perfectly
  9. """
  10. # First, remove patterns like \begin{align}, \phantom{thing},
  11. # \begin{array}{cc}, etc.
  12. pattern = "|".join(
  13. rf"(\\{s})" + r"(\{\w+\})?(\{\w+\})?(\[\w+\])?"
  14. for s in ["begin", "end", "phantom"]
  15. )
  16. tex = re.sub(pattern, "", tex)
  17. # Progressively count the symbols associated with certain tex commands,
  18. # and remove those commands from the string, adding the number of symbols
  19. # that command creates
  20. total = 0
  21. # Start with the special case \sqrt[number]
  22. for substr in re.findall(r"\\sqrt\[[0-9]+\]", tex):
  23. total += len(substr) - 5 # e.g. \sqrt[3] is 3 symbols
  24. tex = tex.replace(substr, " ")
  25. general_command = r"\\[a-zA-Z!,-/:;<>]+"
  26. for substr in re.findall(general_command, tex):
  27. total += TEX_TO_SYMBOL_COUNT.get(substr, 1)
  28. tex = tex.replace(substr, " ")
  29. # Count remaining characters
  30. total += sum(map(lambda c: c not in "^{} \n\t_$\\&", tex))
  31. return total