1212
1313logger = logging .getLogger ('termtosvg' )
1414
15- USAGE = """termtosvg [output_path] [-c COMMAND] [-g GEOMETRY] [-m MIN_DURATION]
16- [-M MAX_DURATION] [-s] [-t TEMPLATE] [-h]
15+ DEFAULT_LOOP_DELAY = 1000
16+
17+ USAGE = """termtosvg [output_path] [-c COMMAND] [-D DELAY] [-g GEOMETRY]
18+ [-m MIN_DURATION] [-M MAX_DURATION] [-s] [-t TEMPLATE] [-h]
1719
1820Record a terminal session and render an SVG animation on the fly
1921"""
2022EPILOG = "See also 'termtosvg record --help' and 'termtosvg render --help'"
2123RECORD_USAGE = "termtosvg record [output_path] [-c COMMAND] [-g GEOMETRY] [-h]"
22- RENDER_USAGE = """termtosvg render input_file [output_path] [-m MIN_DURATION ]
23- [-M MAX_DURATION] [-s] [-t TEMPLATE] [-h]"""
24+ RENDER_USAGE = """termtosvg render input_file [output_path] [-D DELAY ]
25+ [-m MIN_DURATION] [- M MAX_DURATION] [-s] [-t TEMPLATE] [-h]"""
2426
2527
26- def integral_duration (duration ):
28+ def integral_duration_validation (duration ):
2729 if duration .lower ().endswith ('ms' ):
2830 duration = duration [:- len ('ms' )]
2931
@@ -33,7 +35,7 @@ def integral_duration(duration):
3335
3436
3537def parse (args , templates , default_template , default_geometry , default_min_dur ,
36- default_max_dur , default_cmd ):
38+ default_max_dur , default_cmd , default_loop_delay ):
3739 """Parse command line arguments
3840
3941 :param args: Arguments to parse
@@ -47,6 +49,8 @@ def parse(args, templates, default_template, default_geometry, default_min_dur,
4749 :param default_max_dur: Default maximal duration between frames in
4850 milliseconds
4951 :param default_cmd: Default program (with argument list) recorded
52+ :param default_loop_delay: Duration of the pause between two consecutive
53+ loops of the animation in milliseconds
5054 :return: Tuple made of the subcommand called (None, 'render' or 'record')
5155 and all parsed
5256 arguments
@@ -91,7 +95,7 @@ def parse(args, templates, default_template, default_geometry, default_min_dur,
9195 min_duration_parser = argparse .ArgumentParser (add_help = False )
9296 min_duration_parser .add_argument (
9397 '-m' , '--min-frame-duration' ,
94- type = integral_duration ,
98+ type = integral_duration_validation ,
9599 metavar = 'MIN_DURATION' ,
96100 default = default_min_dur ,
97101 help = ('minimum duration of a frame in milliseconds (default: {}ms)'
@@ -106,16 +110,29 @@ def parse(args, templates, default_template, default_geometry, default_min_dur,
106110 max_duration_parser = argparse .ArgumentParser (add_help = False )
107111 max_duration_parser .add_argument (
108112 '-M' , '--max-frame-duration' ,
109- type = integral_duration ,
113+ type = integral_duration_validation ,
110114 metavar = 'MAX_DURATION' ,
111115 default = default_max_dur ,
112116 help = ('maximum duration of a frame in milliseconds (default: {})'
113117 .format (default_max_dur_label ))
114118 )
119+
120+ loop_delay_parser = argparse .ArgumentParser (add_help = False )
121+ loop_delay_parser .add_argument (
122+ '-D' , '--loop-delay' ,
123+ type = integral_duration_validation ,
124+ metavar = 'DELAY' ,
125+ default = default_loop_delay ,
126+ help = (('duration in milliseconds of the pause between two consecutive '
127+ 'loops of the animation (default: {}ms)' )
128+ .format (default_loop_delay ))
129+ )
130+
115131 parser = argparse .ArgumentParser (
116132 prog = 'termtosvg' ,
117133 parents = [command_parser , geometry_parser , min_duration_parser ,
118- max_duration_parser , still_frames_parser , template_parser ],
134+ max_duration_parser , still_frames_parser , template_parser ,
135+ loop_delay_parser ],
119136 usage = USAGE ,
120137 epilog = EPILOG
121138 )
@@ -148,7 +165,8 @@ def parse(args, templates, default_template, default_geometry, default_min_dur,
148165 parser = argparse .ArgumentParser (
149166 description = 'render an asciicast recording as an SVG animation' ,
150167 parents = [template_parser , min_duration_parser ,
151- max_duration_parser , still_frames_parser ],
168+ max_duration_parser , still_frames_parser ,
169+ loop_delay_parser ],
152170 usage = RENDER_USAGE
153171 )
154172 parser .add_argument (
@@ -191,15 +209,15 @@ def record_subcommand(process_args, geometry, input_fileno, output_fileno,
191209
192210
193211def render_subcommand (still , template , cast_filename , output_path ,
194- min_frame_duration , max_frame_duration ):
212+ min_frame_duration , max_frame_duration , loop_delay ):
195213 """Render the animation from an asciicast recording"""
196214 from termtosvg .asciicast import read_records
197215 from termtosvg .term import timed_frames
198216
199217 logger .info ('Rendering started' )
200218 asciicast_records = read_records (cast_filename )
201219 geometry , frames = timed_frames (asciicast_records , min_frame_duration ,
202- max_frame_duration )
220+ max_frame_duration , loop_delay )
203221 if still :
204222 termtosvg .anim .render_still_frames (frames = frames ,
205223 geometry = geometry ,
@@ -217,7 +235,8 @@ def render_subcommand(still, template, cast_filename, output_path,
217235
218236def record_render_subcommand (process_args , still , template , geometry ,
219237 input_fileno , output_fileno , output_path ,
220- min_frame_duration , max_frame_duration ):
238+ min_frame_duration , max_frame_duration ,
239+ loop_delay ):
221240 """Record and render the animation on the fly"""
222241 from termtosvg .term import get_terminal_size , TerminalMode , record , timed_frames
223242
@@ -233,7 +252,7 @@ def record_render_subcommand(process_args, still, template, geometry,
233252 asciicast_records = record (process_args , columns , lines , input_fileno ,
234253 output_fileno )
235254 geometry , frames = timed_frames (asciicast_records , min_frame_duration ,
236- max_frame_duration )
255+ max_frame_duration , loop_delay )
237256
238257 if still :
239258 termtosvg .anim .render_still_frames (frames , geometry , output_path ,
@@ -266,7 +285,7 @@ def main(args=None, input_fileno=None, output_fileno=None):
266285 default_template = 'gjm8' if 'gjm8' in templates else sorted (templates )[0 ]
267286 default_cmd = os .environ .get ('SHELL' , 'sh' )
268287 command , args = parse (args [1 :], templates , default_template , None , 1 ,
269- None , default_cmd )
288+ None , default_cmd , DEFAULT_LOOP_DELAY )
270289
271290 if command == 'record' :
272291 if args .output_path is None :
@@ -295,7 +314,7 @@ def main(args=None, input_fileno=None, output_fileno=None):
295314
296315 render_subcommand (args .still_frames , args .template , args .input_file ,
297316 output_path , args .min_frame_duration ,
298- args .max_frame_duration )
317+ args .max_frame_duration , args . loop_delay )
299318 else :
300319 if args .output_path is None :
301320 if args .still_frames :
@@ -317,7 +336,8 @@ def main(args=None, input_fileno=None, output_fileno=None):
317336 args .screen_geometry , input_fileno ,
318337 output_fileno , output_path ,
319338 args .min_frame_duration ,
320- args .max_frame_duration )
339+ args .max_frame_duration ,
340+ args .loop_delay )
321341
322342 for handler in logger .handlers :
323343 handler .close ()
0 commit comments