22from argparse import ArgumentParser
33from pathlib import Path
44
5+ from PIL import Image
6+
57INFO : dict [str , tuple [int , str ]] = dict (
68 heading_code = (550 , "## Heading 2" ),
79 list_table = (550 , "" ),
1214
1315
1416def main (name : str ) -> None :
15- in_file = Path (f"demo/{ name } .md" )
16- assert in_file .exists ()
17+ file = Path (f"demo/{ name } .md" )
18+ assert file .exists ()
19+
20+ create_gif (name , file )
21+ create_screenshot (name )
22+
1723
18- out_file = Path (f"demo/{ name } .gif" )
19- if out_file .exists ():
20- out_file .unlink ()
24+ def create_gif (name : str , file : Path ) -> None :
25+ gif = Path (f"demo/{ name } .gif" )
26+ if gif .exists ():
27+ gif .unlink ()
2128
2229 height , content = INFO [name ]
2330
2431 tape = Path ("demo/demo.tape" )
25- tape .write_text (tape_content (in_file , out_file , height , content ))
32+ tape .write_text (tape_content (file , gif , height , content ))
2633 result = subprocess .run (["vhs" , tape ])
2734 assert result .returncode == 0
2835 tape .unlink ()
2936
3037
31- def tape_content (in_file : Path , out_file : Path , height : int , to_write : str ) -> str :
32- content = Path ("demo/format.tape" ).read_text ()
33- content = content .replace ("INPUT" , str (in_file ))
34- content = content .replace ("OUTPUT" , str (out_file ))
35- content = content .replace ("WIDTH" , str (550 ))
36- content = content .replace ("HEIGHT" , str (height ))
37- content = content .replace ("WRITE" , get_write (to_write ))
38- content = content .replace ("MOVE" , get_move (in_file ))
39- return content
38+ def create_screenshot (name : str ) -> None :
39+ screenshot = Path (f"demo/{ name } .png" )
40+ if screenshot .exists ():
41+ screenshot .unlink ()
42+
43+ default , rendered = Path ("default.png" ), Path ("rendered.png" )
44+ assert default .exists () and rendered .exists ()
45+
46+ left , right = Image .open (default ), Image .open (rendered )
47+
48+ mode , width , height = left .mode , left .width , left .height
49+ assert mode == right .mode and width == right .width and height == right .height
50+
51+ combined = Image .new (mode , (2 * width , height ))
52+ combined .paste (left , (0 , 0 ))
53+ combined .paste (right , (width , 0 ))
54+ combined .save (screenshot )
55+
56+ default .unlink ()
57+ rendered .unlink ()
58+
59+
60+ def tape_content (file : Path , gif : Path , height : int , content : str ) -> str :
61+ result = Path ("demo/format.tape" ).read_text ()
62+ result = result .replace ("INPUT" , str (file ))
63+ result = result .replace ("OUTPUT" , str (gif ))
64+ result = result .replace ("WIDTH" , str (550 ))
65+ result = result .replace ("HEIGHT" , str (height ))
66+ result = result .replace ("WRITE" , get_write (content ))
67+ result = result .replace ("MOVE" , get_move (file ))
68+ return result
4069
4170
4271def get_write (content : str ) -> str :
@@ -49,10 +78,10 @@ def get_write(content: str) -> str:
4978 return "\n " .join (write )
5079
5180
52- def get_move (in_file : Path ) -> str :
81+ def get_move (file : Path ) -> str :
5382 move : list [str ] = []
54- # Get lines so we know how to scroll down, account for starting on first line
55- lines : list [str ] = Path ( in_file ) .read_text ().splitlines ()[1 :]
83+ # Get lines so we know how to scroll down, account for starting on second line
84+ lines : list [str ] = file .read_text ().splitlines ()[2 :]
5685 for line in lines :
5786 skip = (" " , "def" , "if" )
5887 duration = 0.1 if line == "" or line .startswith (skip ) else 0.75
0 commit comments