Beispiel #1
0
def render_subcommand(template, cast_filename, svg_filename):
    """Render the animation from an asciicast recording"""
    import termtosvg.asciicast as asciicast
    import termtosvg.term as term

    logger.info('Rendering started')
    asciicast_records = asciicast.read_records(cast_filename)
    replayed_records = term.replay(records=asciicast_records,
                                   from_pyte_char=anim.CharacterCell.from_pyte)
    anim.render_animation(records=replayed_records,
                          filename=svg_filename,
                          template=template)
    logger.info('Rendering ended, SVG animation is {}'.format(svg_filename))
Beispiel #2
0
 def test_render_animation(self):
     frames = [
         term.TimedFrame(0, 60, {
             0: line(0),
         }),
         term.TimedFrame(60, 60, {
             0: line(0),
             1: line(1),
         }),
         term.TimedFrame(120, 60, {
             2: line(2),
             3: line(3),
         }),
     ]
     _, filename = tempfile.mkstemp(prefix='termtosvg_', suffix='.svg')
     anim.render_animation(frames, (80, 24), filename, TEMPLATE)
     with open(filename) as f:
         anim.validate_svg(f)
Beispiel #3
0
def record_render_subcommand(template, geometry, input_fileno, output_fileno,
                             svg_filename):
    """Record and render the animation on the fly"""
    import termtosvg.term as term

    logger.info('Recording started, enter "exit" command or Control-D to end')
    if geometry is None:
        columns, lines = term.get_terminal_size(output_fileno)
    else:
        columns, lines = geometry
    with term.TerminalMode(input_fileno):
        asciicast_records = term.record(columns, lines, input_fileno,
                                        output_fileno)
        replayed_records = term.replay(
            records=asciicast_records,
            from_pyte_char=anim.CharacterCell.from_pyte)
        anim.render_animation(records=replayed_records,
                              filename=svg_filename,
                              template=template)
    logger.info('Recording ended, SVG animation is {}'.format(svg_filename))
Beispiel #4
0
    def test_render_animation(self):
        def line(i):
            chars = [anim.CharacterCell(c, '#123456', '#789012') for c in 'line{}'.format(i)]
            return dict(enumerate(chars))

        records = [
            anim.CharacterCellConfig(80, 24, 'black', 'black'),
            anim.CharacterCellLineEvent(1, line(1), 0, 60),
            anim.CharacterCellLineEvent(2, line(2), 60, 60),
            anim.CharacterCellLineEvent(3, line(3), 120, 60),
            anim.CharacterCellLineEvent(4, line(4), 180, 60),
            # Definition reuse
            anim.CharacterCellLineEvent(5, line(4), 240, 60),
            # Override line for animation chaining
            anim.CharacterCellLineEvent(5, line(6), 300, 60),
        ]

        _, filename = tempfile.mkstemp(prefix='termtosvg_')
        anim.render_animation(records, filename)
        os.remove(filename)
Beispiel #5
0
def render_file(cast_file, svg_file, theme=None):
    asciicast_records = asciicast.read_records(str(cast_file))
    geometry, frames = term.timed_frames(asciicast_records)

    tmpl = config.default_templates()[theme or DEFAULT_THEME]
    anim.render_animation(frames, geometry, str(svg_file), tmpl)
Beispiel #6
0
def main(args=None, input_fileno=None, output_fileno=None):
    # type: (List, Union[int, None], Union[int, None]) -> None
    if args is None:
        args = sys.argv
    if input_fileno is None:
        input_fileno = sys.stdin.fileno()
    if output_fileno is None:
        output_fileno = sys.stdout.fileno()

    console_handler = logging.StreamHandler(sys.stderr)
    console_handler.setLevel(logging.INFO)
    console_formatter = logging.Formatter('%(message)s')
    console_handler.setFormatter(console_formatter)
    logger.handlers = [console_handler]
    logger.setLevel(logging.INFO)

    configuration = config.init_read_conf()
    available_themes = config.CaseInsensitiveDict(**configuration)
    del available_themes['global']

    command, args = parse(args[1:], available_themes)

    if args.verbose:
        _, log_filename = tempfile.mkstemp(prefix='termtosvg_', suffix='.log')
        file_handler = logging.FileHandler(filename=log_filename, mode='w')
        file_handler.setLevel(logging.DEBUG)
        file_formatter = logging.Formatter(
            '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        file_handler.setFormatter(file_formatter)
        logger.handlers.append(file_handler)
        logger.info('Logging to {}'.format(log_filename))

    if command == 'record':
        logger.info(
            'Recording started, enter "exit" command or Control-D to end')
        if args.output_file is None:
            _, cast_filename = tempfile.mkstemp(prefix='termtosvg_',
                                                suffix='.cast')
        else:
            cast_filename = args.output_file

        columns, lines = term.get_terminal_size(output_fileno)
        with term.TerminalMode(input_fileno):
            records = term.record(columns, lines, input_fileno, output_fileno)
            with open(cast_filename, 'w') as cast_file:
                for record in records:
                    print(record.to_json_line(), file=cast_file)

        logger.info('Recording ended, cast file is {}'.format(cast_filename))
    elif command == 'render':
        logger.info('Rendering started')
        if args.output_file is None:
            _, svg_filename = tempfile.mkstemp(prefix='termtosvg_',
                                               suffix='.svg')
        else:
            svg_filename = args.output_file

        if args.font is None:
            font = configuration['GLOBAL']['font']
        else:
            font = args.font

        fallback_theme_name = configuration['GLOBAL']['theme']
        fallback_theme = configuration[fallback_theme_name]
        cli_theme = configuration.get(args.theme)

        records = asciicast.read_records(args.input_file)
        replayed_records = term.replay(
            records=records,
            from_pyte_char=anim.CharacterCell.from_pyte,
            override_theme=cli_theme,
            fallback_theme=fallback_theme)
        anim.render_animation(replayed_records, svg_filename, font)

        logger.info(
            'Rendering ended, SVG animation is {}'.format(svg_filename))
    else:
        # No command passed: record and render on the fly
        logger.info(
            'Recording started, enter "exit" command or Control-D to end')
        if args.output_file is None:
            _, svg_filename = tempfile.mkstemp(prefix='termtosvg_',
                                               suffix='.svg')
        else:
            svg_filename = args.output_file

        columns, lines = term.get_terminal_size(output_fileno)

        if args.font is None:
            font = configuration['GLOBAL']['font']
        else:
            font = args.font

        fallback_theme_name = configuration['GLOBAL']['theme']
        fallback_theme = configuration[fallback_theme_name]
        cli_theme = configuration.get(args.theme)
        with term.TerminalMode(input_fileno):
            records = term.record(columns, lines, input_fileno, output_fileno)
            replayed_records = term.replay(
                records=records,
                from_pyte_char=anim.CharacterCell.from_pyte,
                override_theme=cli_theme,
                fallback_theme=fallback_theme)
            anim.render_animation(replayed_records, svg_filename, font)

        logger.info(
            'Recording ended, SVG animation is {}'.format(svg_filename))

    for handler in logger.handlers:
        handler.close()
Beispiel #7
0
def main(args=None, input_fileno=None, output_fileno=None):
    # type: (List, Union[int, None], Union[int, None]) -> None
    if args is None:
        args = sys.argv
    if input_fileno is None:
        input_fileno = sys.stdin.fileno()
    if output_fileno is None:
        output_fileno = sys.stdout.fileno()

    command, args = parse(args[1:])

    logger = logging.getLogger('termtosvg')
    logger.setLevel(logging.INFO)

    console_handler = logging.StreamHandler(sys.stderr)
    console_handler.setLevel(logging.INFO)
    console_formatter = logging.Formatter('%(message)s')
    console_handler.setFormatter(console_formatter)
    logger.handlers = [console_handler]

    if args.verbose:
        file_handler = logging.FileHandler(filename=LOG_FILENAME, mode='w')
        file_handler.setLevel(logging.DEBUG)
        file_formatter = logging.Formatter(
            '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        file_handler.setFormatter(file_formatter)
        logger.handlers.append(file_handler)
        logger.info('Logging to {}'.format(LOG_FILENAME))

    fallback_theme_name = 'solarized-dark'
    xresources_str = term.default_themes()[fallback_theme_name]
    fallback_theme = asciicast.AsciiCastTheme.from_xresources(xresources_str)

    if command == 'record':
        logger.info(
            'Recording started, enter "exit" command or Control-D to end')
        if args.output_file is None:
            _, cast_filename = tempfile.mkstemp(prefix='termtosvg_',
                                                suffix='.cast')
        else:
            cast_filename = args.output_file

        columns, lines, theme = term.get_configuration(output_fileno)
        with term.TerminalMode(input_fileno):
            records = term.record(columns, lines, theme, input_fileno,
                                  output_fileno)
            with open(cast_filename, 'w') as cast_file:
                for record in records:
                    print(record.to_json_line(), file=cast_file)

        logger.info('Recording ended, cast file is {}'.format(cast_filename))
    elif command == 'render':

        def rec_gen():
            with open(args.input_file, 'r') as cast_file:
                for line in cast_file:
                    yield asciicast.AsciiCastRecord.from_json_line(line)

        logger.info('Rendering started')
        if args.output_file is None:
            _, svg_filename = tempfile.mkstemp(prefix='termtosvg_',
                                               suffix='.svg')
        else:
            svg_filename = args.output_file

        if args.theme is None:
            theme = fallback_theme
        else:
            xresources_str = term.default_themes()[args.theme]
            theme = asciicast.AsciiCastTheme.from_xresources(xresources_str)

        replayed_records = term.replay(rec_gen(), anim.CharacterCell.from_pyte,
                                       theme)
        anim.render_animation(replayed_records, svg_filename)

        logger.info(
            'Rendering ended, SVG animation is {}'.format(svg_filename))
    else:
        # No command passed: record and render on the fly
        logger.info(
            'Recording started, enter "exit" command or Control-D to end')
        if args.output_file is None:
            _, svg_filename = tempfile.mkstemp(prefix='termtosvg_',
                                               suffix='.svg')
        else:
            svg_filename = args.output_file

        columns, lines, system_theme = term.get_configuration(output_fileno)

        if args.theme is None:
            if system_theme is None:
                theme = fallback_theme
            else:
                theme = system_theme
        else:
            xresources_str = term.default_themes()[args.theme]
            theme = asciicast.AsciiCastTheme.from_xresources(xresources_str)

        with term.TerminalMode(input_fileno):
            records = term.record(columns, lines, theme, input_fileno,
                                  output_fileno)
            replayed_records = term.replay(records,
                                           anim.CharacterCell.from_pyte, theme)
            anim.render_animation(replayed_records, svg_filename)

        logger.info(
            'Recording ended, SVG animation is {}'.format(svg_filename))

    for handler in logger.handlers:
        handler.close()