3b1b-manim/manimlib/utils/tex_file_writing.py
Thomas Zhu 47d8caa80e Use os.devnull instead of utils.tex_file_writing.get_null(); also small typos that cause SyntaxError (#382)
* Update tex_file_writing.py

* Change "/dev/null" to os.getnull in utils/sounds.py SoX "play" command

* Fix typo
2018-12-29 09:27:03 -08:00

92 lines
2.7 KiB
Python

import os
import hashlib
from manimlib.constants import TEX_DIR
from manimlib.constants import TEX_TEXT_TO_REPLACE
from manimlib.constants import TEX_USE_CTEX
def tex_hash(expression, template_tex_file_body):
id_str = str(expression + template_tex_file_body)
hasher = hashlib.sha256()
hasher.update(id_str.encode())
# Truncating at 16 bytes for cleanliness
return hasher.hexdigest()[:16]
def tex_to_svg_file(expression, template_tex_file_body):
tex_file = generate_tex_file(expression, template_tex_file_body)
dvi_file = tex_to_dvi(tex_file)
return dvi_to_svg(dvi_file)
def generate_tex_file(expression, template_tex_file_body):
result = os.path.join(
TEX_DIR,
tex_hash(expression, template_tex_file_body)
) + ".tex"
if not os.path.exists(result):
print("Writing \"%s\" to %s" % (
"".join(expression), result
))
new_body = template_tex_file_body.replace(
TEX_TEXT_TO_REPLACE, expression
)
with open(result, "w") as outfile:
outfile.write(new_body)
return result
def tex_to_dvi(tex_file):
result = tex_file.replace(".tex", ".dvi" if not TEX_USE_CTEX else ".xdv")
if not os.path.exists(result):
commands = [
"latex",
"-interaction=batchmode",
"-halt-on-error",
"-output-directory=" + TEX_DIR,
tex_file,
">",
os.devnull
] if not TEX_USE_CTEX else [
"xelatex",
"-no-pdf",
"-interaction=batchmode",
"-halt-on-error",
"-output-directory=" + TEX_DIR,
tex_file,
">",
os.devnull
]
exit_code = os.system(" ".join(commands))
if exit_code != 0:
log_file = tex_file.replace(".tex", ".log")
raise Exception(
("Latex error converting to dvi. " if not TEX_USE_CTEX
else "Xelatex error converting to xdv. ") +
"See log output above or the log file: %s" % log_file)
return result
def dvi_to_svg(dvi_file, regen_if_exists=False):
"""
Converts a dvi, which potentially has multiple slides, into a
directory full of enumerated pngs corresponding with these slides.
Returns a list of PIL Image objects for these images sorted as they
where in the dvi
"""
result = dvi_file.replace(".dvi" if not TEX_USE_CTEX else ".xdv", ".svg")
if not os.path.exists(result):
commands = [
"dvisvgm",
dvi_file,
"-n",
"-v",
"0",
"-o",
result,
">",
os.devnull
]
os.system(" ".join(commands))
return result