|
| 1 | +import subprocess |
| 2 | +from argparse import ArgumentParser |
| 3 | +from pathlib import Path |
| 4 | + |
| 5 | + |
| 6 | +def main(name: str, height: int, content: str): |
| 7 | + in_file = Path(f"demo/{name}.md") |
| 8 | + assert in_file.exists() |
| 9 | + |
| 10 | + out_file = Path(f"demo/{name}.gif") |
| 11 | + if out_file.exists(): |
| 12 | + out_file.unlink() |
| 13 | + |
| 14 | + tape = Path("demo/demo.tape") |
| 15 | + tape.write_text(tape_content(in_file, out_file, height, content)) |
| 16 | + result = subprocess.run(["vhs", tape]) |
| 17 | + assert result.returncode == 0 |
| 18 | + tape.unlink() |
| 19 | + |
| 20 | + |
| 21 | +def tape_content(in_file: Path, out_file: Path, height: int, to_write: str) -> str: |
| 22 | + content = Path("demo/format.tape").read_text() |
| 23 | + content = content.replace("INPUT", str(in_file)) |
| 24 | + content = content.replace("OUTPUT", str(out_file)) |
| 25 | + content = content.replace("WIDTH", str(550)) |
| 26 | + content = content.replace("HEIGHT", str(height)) |
| 27 | + content = content.replace("WRITE", get_write(to_write)) |
| 28 | + content = content.replace("MOVE", get_move(in_file)) |
| 29 | + return content |
| 30 | + |
| 31 | + |
| 32 | +def get_write(content: str) -> str: |
| 33 | + write: list[str] = [] |
| 34 | + if len(content) > 0: |
| 35 | + write.append('Type "o"') |
| 36 | + write.append("Enter") |
| 37 | + write.append(f'Type "{content}" Escape') |
| 38 | + write.append('Type "0" Sleep 2s') |
| 39 | + return "\n".join(write) |
| 40 | + |
| 41 | + |
| 42 | +def get_move(in_file: Path) -> str: |
| 43 | + move: list[str] = [] |
| 44 | + # Get lines so we know how to scroll down, account for starting on first line |
| 45 | + lines: list[str] = Path(in_file).read_text().splitlines()[1:] |
| 46 | + for line in lines: |
| 47 | + skip = (" ", "def", "if") |
| 48 | + duration = 0.1 if line == "" or line.startswith(skip) else 0.75 |
| 49 | + move.append(f"Down@{duration}s") |
| 50 | + return "\n".join(move) |
| 51 | + |
| 52 | + |
| 53 | +if __name__ == "__main__": |
| 54 | + parser = ArgumentParser(description="Generate a demo recording using vhs") |
| 55 | + parser.add_argument("--name", type=str, required=True) |
| 56 | + parser.add_argument("--height", type=int, required=True) |
| 57 | + parser.add_argument("--content", type=str, required=True) |
| 58 | + args = parser.parse_args() |
| 59 | + main(args.name, args.height, args.content) |
0 commit comments