Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ Commands registered on the **`docgen`** CLI include:
## Implications for changes here

- **Manim / `scenes.py` (marker blocks):** Fix generators under `src/docgen/**` (`manim_scene_support.py`, `scene_spec.py`, `scene_spec_generate.py`, `validate`, `yaml_generate`, tests). **Do not** patch generated classes inside a consumer's **`animations/scenes.py`** between **`BEGIN/END GENERATED SCENE`** markers; re-run **`scene-spec-generate`** / **`scene-compile --retime`** and **`manim`** instead. Preferred consumer order: narration → TTS → timestamps → scene-spec/compile → Manim → compose.
- **Beat sync (fail-closed):** when `timing.json` has words, every story box label must match a spoken phrase (`wait_word`); unmatched labels and leftover LLM indices are rejected. Opt out with ``pace: none``. Fuzzy containment matching is not used.
- **Beat sync (fail-closed):** when `timing.json` has words, every story box label must match a spoken phrase (`wait_word`); unmatched labels and leftover LLM indices are rejected. Opt out with ``pace: none``. Fuzzy containment matching is not used. **`scene-compile` clamps FadeIn / page-fade `run_time` against the next word start** so `_TimedScene._clock` cannot race past waits (issue #66 — do not emit cascading first-board dumps). Page transitions FadeOut revealed boxes, not the parent `VGroup`.
- **Subject-beat coverage:** implemented in `scene_spec.layout_density_violations` / `cluster_subject_beats`; enforced by **`scene-spec-generate`** and **`validate`** (`validation.subject_beat_coverage.enabled`, default true). Not a blind label count.
- Prefer **stable CLI / library contracts** and **documented exit codes** so CI can depend on them.
- **`narration_from_source`:** hints in config + **`docgen narration-generate`** — owner-supplied context paths, not opaque bulk edits to outputs.
Expand Down
20 changes: 17 additions & 3 deletions src/docgen/manim_scene_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,9 +243,23 @@ class _TimedScene(Scene):
def setup(self):
self._clock = 0.0

def timed_play(self, *animations, run_time=1.0, **kwargs):
self.play(*animations, run_time=run_time, **kwargs)
self._clock += run_time
def timed_play(self, *animations, run_time=1.0, not_past=None, **kwargs):
"""Play animations and advance ``_clock``.

Optional ``not_past`` (absolute seconds) clamps ``run_time`` so the clock
cannot race past the next paced reveal — defense in depth when compiled
run_times were not clamped (issue #66).
"""
rt = float(run_time)
if not_past is not None:
try:
limit = float(not_past)
except (TypeError, ValueError):
limit = None
if limit is not None and self._clock + rt > limit:
rt = max(0.25, limit - self._clock)
self.play(*animations, run_time=rt, **kwargs)
self._clock += rt

def wait_until(self, target: float):
gap = target - self._clock
Expand Down
Loading