Skip to content

Commit

Permalink
feat: implement Code theme parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
YishiMichael committed Dec 19, 2023
1 parent 118c6da commit 9812475
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 42 deletions.
16 changes: 6 additions & 10 deletions examples/formula.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,16 @@ async def construct(
self: Self
) -> None:
factored_formula = Math(
"(a_0^2 + a_1^2) (b_0^2 + b_1^2 + b_2^2)"
"(a_0 + a_1) (b_0 + b_1 + b_2)"
).set_local_colors({
"a": TEAL,
re.compile(r"(?<=a_)\d"): TEAL,
"b": ORANGE,
re.compile(r"(?<=b_)\d"): ORANGE
re.compile(r"a_\d"): TEAL,
re.compile(r"b_\d"): ORANGE
}).shift(UP)
expanded_formula = Math(
"a_0^2 b_0^2 + a_0^2 b_1^2 + a_0^2 b_2^2 + a_1^2 b_0^2 + a_1^2 b_1^2 + a_1^2 b_2^2"
"a_0 b_0 + a_0 b_1 + a_0 b_2 + a_1 b_0 + a_1 b_1 + a_1 b_2"
).set_local_colors({
"a": TEAL,
re.compile(r"(?<=a_)\d"): TEAL,
"b": ORANGE,
re.compile(r"(?<=b_)\d"): ORANGE
re.compile(r"a_\d"): TEAL,
re.compile(r"b_\d"): ORANGE
}).shift(DOWN)
self.add(factored_formula)
await self.wait()
Expand Down
27 changes: 25 additions & 2 deletions manim3/mobjects/string_mobjects/code_mobject.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from __future__ import annotations
import itertools


import pathlib
from typing import (
Self,
Unpack
Expand All @@ -20,11 +22,18 @@

class CodeKwargs(TypstMobjectKwargs, total=False):
syntax: str
theme: str | pathlib.Path | None


@attrs.frozen(kw_only=True)
class CodeInputs(TypstMobjectInputs):
syntax: str = attrs.field(factory=lambda: Toplevel._get_config().code_syntax)
syntax: str = attrs.field(
factory=lambda: Toplevel._get_config().code_syntax
)
theme: pathlib.Path | None = attrs.field(
factory=lambda: Toplevel._get_config().code_theme,
converter=lambda theme: None if theme is None else pathlib.Path(theme) if isinstance(theme, str) else theme
)


class Code(TypstMobject[CodeInputs]):
Expand All @@ -37,10 +46,24 @@ def __init__(
) -> None:
super().__init__(CodeInputs(string=string, **kwargs))

@classmethod
def _get_preamble_from_inputs(
cls: type[Self],
inputs: CodeInputs,
temp_path: pathlib.Path
) -> str:
return "\n".join(filter(None, (
super()._get_preamble_from_inputs(inputs, temp_path),
f"""#set raw(theme: "{
pathlib.Path("/".join(itertools.repeat("..", len(temp_path.parts) - 1))).joinpath(inputs.theme)
}")""" if inputs.theme is not None else ""
)))

@classmethod
def _get_environment_pair_from_inputs(
cls: type[Self],
inputs: CodeInputs
inputs: CodeInputs,
temp_path: pathlib.Path
) -> tuple[str, str]:
return f"```{inputs.syntax}\n", "\n```"

Expand Down
8 changes: 6 additions & 2 deletions manim3/mobjects/string_mobjects/math_mobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@


import itertools
import pathlib
import re
from typing import (
Self,
Expand All @@ -25,7 +26,9 @@ class MathKwargs(TypstMobjectKwargs, total=False):

@attrs.frozen(kw_only=True)
class MathInputs(TypstMobjectInputs):
inline: bool = attrs.field(factory=lambda: Toplevel._get_config().math_inline)
inline: bool = attrs.field(
factory=lambda: Toplevel._get_config().math_inline
)


class Math(TypstMobject[MathInputs]):
Expand All @@ -41,7 +44,8 @@ def __init__(
@classmethod
def _get_environment_pair_from_inputs(
cls: type[Self],
inputs: MathInputs
inputs: MathInputs,
temp_path: pathlib.Path
) -> tuple[str, str]:
if inputs.inline:
return "$", "$"
Expand Down
73 changes: 45 additions & 28 deletions manim3/mobjects/string_mobjects/typst_mobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,23 @@ def _docstring_trim(
trimmed.pop(0)
return "\n".join(trimmed)

string: str = attrs.field(converter=_docstring_trim)
preamble: str = attrs.field(factory=lambda: Toplevel._get_config().typst_preamble, converter=_docstring_trim)
string: str = attrs.field(
converter=_docstring_trim
)
preamble: str = attrs.field(
factory=lambda: Toplevel._get_config().typst_preamble,
converter=_docstring_trim
)
concatenate: bool = False
align: str | None = attrs.field(factory=lambda: Toplevel._get_config().typst_align)
font: str | tuple[str, ...] | None = attrs.field(factory=lambda: Toplevel._get_config().typst_font)
color: ColorType | None = attrs.field(factory=lambda: Toplevel._get_config().default_color)
align: str | None = attrs.field(
factory=lambda: Toplevel._get_config().typst_align
)
font: str | tuple[str, ...] | None = attrs.field(
factory=lambda: Toplevel._get_config().typst_font
)
color: ColorType | None = attrs.field(
factory=lambda: Toplevel._get_config().default_color
)


class TypstMobject[TypstMobjectInputsT: TypstMobjectInputs](CachedMobject[TypstMobjectInputsT]):
Expand All @@ -93,8 +104,8 @@ def _generate_shape_mobjects(
inputs: TypstMobjectInputsT,
temp_path: pathlib.Path
) -> tuple[ShapeMobject, ...]:
preamble = cls._get_preamble_from_inputs(inputs)
environment_begin, environment_end = cls._get_environment_pair_from_inputs(inputs)
preamble = cls._get_preamble_from_inputs(inputs, temp_path)
environment_begin, environment_end = cls._get_environment_pair_from_inputs(inputs, temp_path)
content = "\n".join(filter(None, (
preamble,
inputs.preamble,
Expand All @@ -106,18 +117,14 @@ def _generate_shape_mobjects(
typst_path.write_text(content, encoding="utf-8")

try:
if (stdout := subprocess.check_output((
subprocess.check_output((
"typst",
"compile",
"--root", pathlib.Path(),
typst_path,
svg_path
))):
error = OSError("Typst error")
error.add_note(stdout.decode())
raise error

), stderr=subprocess.STDOUT)
shape_mobjects = SVGMobject._generate_shape_mobjects_from_svg(svg_path)

finally:
for path in (svg_path, typst_path):
path.unlink(missing_ok=True)
Expand All @@ -131,7 +138,8 @@ def _generate_shape_mobjects(
@classmethod
def _get_preamble_from_inputs(
cls: type[Self],
inputs: TypstMobjectInputsT
inputs: TypstMobjectInputsT,
temp_path: pathlib.Path
) -> str:
return "\n".join(filter(None, (
f"""#set align({
Expand All @@ -150,7 +158,8 @@ def _get_preamble_from_inputs(
@classmethod
def _get_environment_pair_from_inputs(
cls: type[Self],
inputs: TypstMobjectInputsT
inputs: TypstMobjectInputsT,
temp_path: pathlib.Path
) -> tuple[str, str]:
return "", ""

Expand All @@ -163,16 +172,7 @@ def _get_labelled_inputs(
) -> TypstMobjectInputsT:
pass

def _build_from_selector(
self: Self,
selector: SelectorType
) -> ShapeMobject:
return ShapeMobject().add(*(
self._shape_mobjects[index]
for index in self._selector_to_indices_dict[selector]
))

def probe(
def _probe_indices_from_selectors(
self: Self,
selectors: tuple[SelectorType, ...]
) -> None:
Expand Down Expand Up @@ -204,18 +204,27 @@ def probe(
continue
self._selector_to_indices_dict[label_to_selector_dict[label]].append(index)

def _build_from_selector(
self: Self,
selector: SelectorType
) -> ShapeMobject:
return ShapeMobject().add(*(
self._shape_mobjects[index]
for index in self._selector_to_indices_dict[selector]
))

def select(
self: Self,
selector: SelectorType
) -> ShapeMobject:
self.probe((selector,))
self._probe_indices_from_selectors((selector,))
return self._build_from_selector(selector)

def set_local_styles(
self: Self,
selector_to_kwargs_dict: dict[SelectorType, SetKwargs]
) -> Self:
self.probe(tuple(selector_to_kwargs_dict))
self._probe_indices_from_selectors(tuple(selector_to_kwargs_dict))
for selector, kwargs in selector_to_kwargs_dict.items():
self._build_from_selector(selector).set(**kwargs)
return self
Expand All @@ -229,3 +238,11 @@ def set_local_colors(
for selector, color in selector_to_color_dict.items()
})
return self

def set_local_color(
self: Self,
selector: SelectorType,
color: ColorType
) -> Self:
self.set_local_colors({selector: color})
return self
1 change: 1 addition & 0 deletions manim3/toplevel/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class Config(ToplevelResource):
typst_font: str | tuple[str, ...] | None = None
math_inline: bool = False
code_syntax: str = "py"
code_theme: pathlib.Path | None = None

shader_search_dirs: tuple[pathlib.Path, ...] = (
pathlib.Path(),
Expand Down

0 comments on commit 9812475

Please sign in to comment.