Skip to content

Commit 4816fc9

Browse files
authored
feat: large "present" feature refactoring (#15)
* fix(cli): previous presentation starts last slide This changes the previous behavior that was such that going to previous presentation (scene) would start it from zero. * fix(README): remove non-working svgs Seems like GitHub does not support that * wip: onto a cleaner parser, and more robust presentation * fix(README): remove non-working svgs Seems like GitHub does not support that * wip: onto a cleaner parser, and more robust presentation * wip: some progress * fix: this is kinda working now * fix: repeated reversed slide * fix: import __version__ without importing package * fix: typing list -> List * chore(README): update features
1 parent f6f851b commit 4816fc9

File tree

6 files changed

+361
-166
lines changed

6 files changed

+361
-166
lines changed

README.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -113,14 +113,14 @@ manim-slides Example
113113

114114
The default key bindings to control the presentation are:
115115

116-
| Keybinding | Action | Icon |
117-
|:-----------:|:------------------------:|:----:|
118-
| Right Arrow | Continue/Next Slide | <svg height="25px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Pro 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M52.5 440.6c-9.5 7.9-22.8 9.7-34.1 4.4S0 428.4 0 416V96C0 83.6 7.2 72.3 18.4 67s24.5-3.6 34.1 4.4l192 160L256 241V96c0-17.7 14.3-32 32-32s32 14.3 32 32V416c0 17.7-14.3 32-32 32s-32-14.3-32-32V271l-11.5 9.6-192 160z"/></svg> |
119-
| Left Arrow | Previous Slide | <svg height="25px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Pro 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M267.5 440.6c9.5 7.9 22.8 9.7 34.1 4.4s18.4-16.6 18.4-29V96c0-12.4-7.2-23.7-18.4-29s-24.5-3.6-34.1 4.4l-192 160L64 241V96c0-17.7-14.3-32-32-32S0 78.3 0 96V416c0 17.7 14.3 32 32 32s32-14.3 32-32V271l11.5 9.6 192 160z"/></svg> |
120-
| R | Replay Current Slide | <svg height="25px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M48.5 224H40c-13.3 0-24-10.7-24-24V72c0-9.7 5.8-18.5 14.8-22.2s19.3-1.7 26.2 5.2L98.6 96.6c87.6-86.5 228.7-86.2 315.8 1c87.5 87.5 87.5 229.3 0 316.8s-229.3 87.5-316.8 0c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0c62.5 62.5 163.8 62.5 226.3 0s62.5-163.8 0-226.3c-62.2-62.2-162.7-62.5-225.3-1L185 183c6.9 6.9 8.9 17.2 5.2 26.2s-12.5 14.8-22.2 14.8H48.5z"/></svg> |
121-
| V | Reverse Current Slide | <svg height="25px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M459.5 440.6c9.5 7.9 22.8 9.7 34.1 4.4s18.4-16.6 18.4-29V96c0-12.4-7.2-23.7-18.4-29s-24.5-3.6-34.1 4.4L288 214.3V256v41.7L459.5 440.6zM256 352V256 128 96c0-12.4-7.2-23.7-18.4-29s-24.5-3.6-34.1 4.4l-192 160C4.2 237.5 0 246.5 0 256s4.2 18.5 11.5 24.6l192 160c9.5 7.9 22.8 9.7 34.1 4.4s18.4-16.6 18.4-29V352z"/></svg> |
122-
| Spacebar | Play/Pause | <svg height="25px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--! Font Awesome Pro 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M73 39c-14.8-9.1-33.4-9.4-48.5-.9S0 62.6 0 80V432c0 17.4 9.4 33.4 24.5 41.9s33.7 8.1 48.5-.9L361 297c14.3-8.7 23-24.2 23-41s-8.7-32.2-23-41L73 39z"/></svg> <svg height="25px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Pro 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M48 64C21.5 64 0 85.5 0 112V400c0 26.5 21.5 48 48 48H80c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48H48zm192 0c-26.5 0-48 21.5-48 48V400c0 26.5 21.5 48 48 48h32c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48H240z"/></svg> |
123-
| Q | Quit | <svg height="25px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Pro 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M310.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L160 210.7 54.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L114.7 256 9.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L160 301.3 265.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L205.3 256 310.6 150.6z"/></svg> |
116+
| Keybinding | Action |
117+
|:-----------:|:------------------------:|
118+
| Right Arrow | Continue/Next Slide |
119+
| Left Arrow | Previous Slide |
120+
| R | Replay Current Slide |
121+
| V | Reverse Current Slide |
122+
| Spacebar | Play/Pause |
123+
| Q | Quit |
124124

125125
You can run the **configuration wizard** to change those key bindings:
126126

@@ -165,7 +165,7 @@ Below is a non-exhaustive list of features:
165165
| One command line tool | :heavy_check_mark: | :heavy_multiplication_x: |
166166
| Robust config file parsing | :heavy_check_mark: | :heavy_multiplication_x: |
167167
| Support for 3D Scenes | :heavy_check_mark: | :heavy_multiplication_x: |
168-
| Documented code | WIP | :heavy_multiplication_x: |
168+
| Documented code | :heavy_check_mark: | :heavy_multiplication_x: |
169169
| Tested on Unix, macOS, and Windows | :heavy_check_mark: | :heavy_multiplication_x: |
170170

171171

manim_slides/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "3.2.4"
1+
__version__ = "4-rc.1"

manim_slides/config.py

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
1-
from typing import Optional, Set
1+
import os
2+
from enum import Enum
3+
from typing import List, Optional, Set
24

3-
from pydantic import BaseModel, root_validator, validator
5+
from pydantic import BaseModel, FilePath, root_validator, validator
46

57
from .defaults import LEFT_ARROW_KEY_CODE, RIGHT_ARROW_KEY_CODE
68

79

810
class Key(BaseModel):
11+
"""Represents a list of key codes, with optionally a name."""
12+
913
ids: Set[int]
1014
name: Optional[str] = None
1115

@@ -20,6 +24,8 @@ def match(self, key_id: int):
2024

2125

2226
class Config(BaseModel):
27+
"""General Manim Slides config"""
28+
2329
QUIT: Key = Key(ids=[ord("q")], name="QUIT")
2430
CONTINUE: Key = Key(ids=[RIGHT_ARROW_KEY_CODE], name="CONTINUE / NEXT")
2531
BACK: Key = Key(ids=[LEFT_ARROW_KEY_CODE], name="BACK")
@@ -47,3 +53,83 @@ def merge_with(self, other: "Config") -> "Config":
4753
key.name = other_key.name or key.name
4854

4955
return self
56+
57+
58+
class SlideType(str, Enum):
59+
slide = "slide"
60+
loop = "loop"
61+
last = "last"
62+
63+
64+
class SlideConfig(BaseModel):
65+
type: SlideType
66+
start_animation: int
67+
end_animation: int
68+
number: int
69+
terminated: bool = False
70+
71+
@validator("start_animation", "end_animation")
72+
def index_is_posint(cls, v: int):
73+
if v < 0:
74+
raise ValueError("Animation index (start or end) cannot be negative")
75+
return v
76+
77+
@validator("number")
78+
def number_is_strictly_posint(cls, v: int):
79+
if v <= 0:
80+
raise ValueError("Slide number cannot be negative or zero")
81+
return v
82+
83+
@root_validator
84+
def start_animation_is_before_end(cls, values):
85+
if values["start_animation"] >= values["end_animation"]:
86+
87+
raise ValueError(
88+
"Start animation index must be strictly lower than end animation index"
89+
)
90+
91+
return values
92+
93+
def is_slide(self):
94+
return self.type == SlideType.slide
95+
96+
def is_loop(self):
97+
return self.type == SlideType.loop
98+
99+
def is_last(self):
100+
return self.type == SlideType.last
101+
102+
103+
class PresentationConfig(BaseModel):
104+
slides: List[SlideConfig]
105+
files: List[str]
106+
107+
@validator("files", pre=True, each_item=True)
108+
def is_file_and_exists(cls, v):
109+
if not os.path.exists(v):
110+
raise ValueError(
111+
f"Animation file {v} does not exist. Are you in the right directory?"
112+
)
113+
114+
if not os.path.isfile(v):
115+
raise ValueError(f"Animation file {v} is not a file")
116+
117+
return v
118+
119+
@root_validator
120+
def animation_indices_match_files(cls, values):
121+
files = values.get("files")
122+
slides = values.get("slides")
123+
124+
if files is None or slides is None:
125+
return values
126+
127+
n_files = len(files)
128+
129+
for slide in slides:
130+
if slide.end_animation > n_files:
131+
raise ValueError(
132+
f"The following slide's contains animations not listed in files {files}: {slide}"
133+
)
134+
135+
return values

0 commit comments

Comments
 (0)