feat(lib): Sphinx directive can now read files (#261)

* feat(lib): Sphinx directive can now read files

You can optionally read a file instead of the Sphinx directive's content

* fix(lib): rst syntax and docs

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Jérome Eertmans
2023-08-29 16:23:54 +02:00
committed by GitHub
parent 9a3a343231
commit bb5b294f40
5 changed files with 57 additions and 32 deletions

View File

@ -70,16 +70,29 @@ render scenes that are defined within doctests, for example::
... def construct(self):
... self.play(Create(dot))
A third application is to render scenes from another specific file::
.. manim-slides:: file.py:FileExample
:hide_source:
:quality: high
.. warning::
The code will be executed with the current working directory
being the same as the one containing the source file. This being said,
you should probably not include examples that rely on external files, since
relative paths risk to be broken.
Options
-------
Options can be passed as follows::
.. manim-slides:: <Class name>
.. manim-slides:: <file>:<Class name>
:<option name>: <value>
The following configuration options are supported by the
directive:
directive::
hide_source
If this flag is present without argument,
@ -110,6 +123,7 @@ import re
import sys
from pathlib import Path
from timeit import timeit
from typing import Tuple
import jinja2
from docutils import nodes
@ -211,7 +225,17 @@ class ManimSlidesDirective(Directive):
global classnamedict
clsname = self.arguments[0]
def split_file_cls(arg: str) -> Tuple[Path, str]:
if ":" in arg:
file, cls = arg.split(":", maxsplit=1)
_, file = self.state.document.settings.env.relfn2path(file)
return Path(file), cls
else:
return None, arg
arguments = [split_file_cls(arg) for arg in self.arguments]
clsname = arguments[0][1]
if clsname not in classnamedict:
classnamedict[clsname] = 1
else:
@ -271,20 +295,24 @@ class ManimSlidesDirective(Directive):
"output_file": output_file,
}
user_code = self.content
if file := arguments[0][0]:
user_code = file.absolute().read_text().splitlines()
else:
user_code = self.content
if user_code[0].startswith(">>> "): # check whether block comes from doctest
user_code = [
line[4:] for line in user_code if line.startswith((">>> ", "... "))
]
code = [
"from manim import *",
*user_code,
f"{clsname}().render()",
]
try:
with tempconfig(example_config):
print(f"Rendering {clsname}...")
run_time = timeit(lambda: exec("\n".join(code), globals()), number=1)
video_dir = config.get_dir("video_dir")
except Exception as e:
@ -306,9 +334,6 @@ class ManimSlidesDirective(Directive):
RevealJS(presentation_configs=presentation_configs, controls="true").convert_to(
destfile
)
# shutil.copyfile(filesrc, destfile)
print("CLASS NAME:", clsname)
rendered_template = jinja2.Template(TEMPLATE).render(
clsname=clsname,
@ -400,6 +425,7 @@ TEMPLATE = r"""
.. raw:: html
<!-- From: https://faq.dailymotion.com/hc/en-us/articles/360022841393-How-to-preserve-the-player-aspect-ratio-on-a-responsive-page -->
<div style="position:relative;padding-bottom:56.25%;">
<iframe