Fixes to gnommo

This commit is contained in:
2026-05-13 08:13:20 +02:00
parent 5d7c77db91
commit cf40a19b4e
6 changed files with 125 additions and 71 deletions
+58 -2
View File
@@ -2394,6 +2394,57 @@ def _parse_slide_range(slides_arg: str) -> tuple[str, Optional[str]]:
return start_slide, end_slide
def _project_markers_to_videos(
markers: list[str], videos_json_path: Path, config
) -> None:
"""ETL: project shorthand marker semantics into videos.json.
Scans the manuscript marker list for shorthand prefixes (vft:, vfb:, vst:,
vsb:, vf2t:, vf2b: and their pause variants) and writes the implied cutout
and layer values directly into videos.json. This runs before parse_videos
so the render pass reads already-projected data and needs no shorthand logic.
The manuscript is the authoritative source: the LAST shorthand reference to
a given video_id wins, matching what a human editor would expect when they
change a marker near the end of the script.
"""
if not videos_json_path.exists():
return
from .transformer import _SHORTHAND_PREFIXES # (cutout, layer) lookup table
# Build projection: video_id → {cutout, layer}
projection: dict[str, dict] = {}
for marker in markers:
for prefix, implied in _SHORTHAND_PREFIXES.items():
if marker.startswith(prefix):
video_id = marker[len(prefix):]
cutout, layer = implied[0], implied[1]
projection[video_id] = {"cutout": cutout, "layer": layer}
break
if not projection:
return
with open(videos_json_path, "r", encoding="utf-8") as f:
raw = json.load(f)
changed = False
for video_id, fields in projection.items():
if video_id not in raw:
continue
for field, value in fields.items():
if raw[video_id].get(field) != value:
raw[video_id][field] = value
changed = True
if changed:
with open(videos_json_path, "w", encoding="utf-8") as f:
json.dump(raw, f, indent=2, ensure_ascii=False)
updated = [vid for vid in projection if vid in raw]
print(f" Projected marker semantics → videos.json: {', '.join(updated)}")
def _writeback_video_metadata(plan, project_path, config) -> None:
"""Write back cutout/layer derived from shorthand markers to videos.json.
@@ -2586,6 +2637,12 @@ def cmd_render(
save_citations(citations, citations_path)
config = parse_project_config(project_path)
# ETL: project shorthand marker semantics (cutout/layer) into videos.json
# before parse_videos reads it, so the render pass is purely data-driven.
_project_markers_to_videos(
markers, project_path / config.videos_path, config
)
# Override resolution for preview modes
if res != "full":
cfg = RES_CONFIGS[res]
@@ -2732,8 +2789,7 @@ def cmd_render(
if plan.time_offset > 0:
print(f" Time offset: {plan.time_offset:.1f}s (partial render)")
# Persist shorthand-derived cutout/layer back to videos.json (idempotent)
_writeback_video_metadata(plan, project_path, config)
# Print detailed render plan with alignment info
_print_render_plan_details(plan, marker_timings, slides)