Ejemplo n.º 1
0
    def render_step(self):
        line = deepcopy(self.code_box.listing.lines[self.position - 1])
        self.undo_line = line

        token = line.parts[-1][0]
        if self._inside_string(line):
            # inside a multi-line string, don't reparse, just append
            parts = deepcopy(line.parts)
            parts[-1] = CodePart(token, parts[-1].text + self.source)
            replace_line = CodeLine(parts, line.lexer)
        else:
            # not inside a string
            if token_is_a(token, String):
                # last token is a string, parse the source and append
                source_line = parse_source(self.source, line.lexer)[0]
                new_parts = line.parts + source_line.parts
                replace_line = CodeLine(new_parts, line.lexer)
            else:
                # last token isn't a string, reparse the whole line
                text = line.text + self.source
                replace_line = parse_source(text, line.lexer)[0]

        if self.cursor:
            replace_line.parts.append(CodePart(Token, '\u2588'))

        self.code_box.listing.replace_line(self.position, replace_line)
Ejemplo n.º 2
0
    def test_misc(self):
        blank = BlankCodeLine()
        self.assertEqual('', blank.render_line(None))

        lexer = PurdyLexer.factory_from_name('py3')
        line = CodeLine([
            CodePart(Token.Text, 'foo'),
        ], lexer, line_number=10)

        expected = 'CodeLine(" 10 foo")'
        self.assertEqual(expected, line.__repr__())
Ejemplo n.º 3
0
    def render_step(self):
        import subprocess

        args = self.cmd.strip().split(' ')

        # subprocess 3.7 command is easier to understand, replace code with
        # whats in comment when py3.6 support is dropped
        #
        #result = subprocess.run(args, capture_output=True, text=True)
        result = subprocess.run(args,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE,
                                universal_newlines=True)

        lexer = PurdyLexer.factory_from_name('con')

        new_lines = []
        for row in result.stdout.split('\n'):
            part = CodePart(Token.Generic.Output, row)
            new_lines.append(CodeLine([
                part,
            ], lexer))

        self.undo_position = len(self.code_box.listing.lines) + 1
        self.undo_size = len(new_lines)
        self.code_box.listing.insert_lines(0, new_lines)
Ejemplo n.º 4
0
    def _line_to_steps(self, line, insert_pos, replace_pos):
        steps = []

        # --- Skip animation for "output" content
        first_token = line.parts[0].token
        is_console = self.code.lexer.is_console

        if is_console and not token_is_a(first_token, Generic.Prompt):
            # in console mode only lines with prompts get typewriter
            # animation, everything else is just added directly
            return [
                steplib.InsertRows(self.code_box, insert_pos, line),
            ]

        # --- Typewriter animation
        # insert a blank row first with contents of line changing what is on
        # it as animation continues
        dummy_parts = [
            CodePart(Token, ''),
        ]
        row_line = CodeLine(dummy_parts, self.code.lexer)
        step = steplib.InsertRows(self.code_box, insert_pos, row_line)
        steps.append(step)

        current_parts = []
        num_parts = len(line.parts)
        for count, part in enumerate(line.parts):
            if part.token in self.continuous:
                # part is a chunk that gets output all together, replace the
                # dummy line with the whole contents
                current_parts.append(part)
                row_line = CodeLine(deepcopy(current_parts), self.code.lexer)
                step = steplib.ReplaceRows(self.code_box, replace_pos,
                                           row_line)
                steps.append(step)

                if part.token == Generic.Prompt:
                    # stop animation if this is a prompt, wait for keypress
                    steps.append(steplib.CellEnd())
            elif count == 0 and token_is_a(
                    part.token, Token.Text) and (part.text.rstrip() == ''):
                # first token is leading whitespace, don't animate it, just
                # insert it
                current_parts.append(part)
                row_line = CodeLine(deepcopy(current_parts), self.code.lexer)
                step = steplib.ReplaceRows(self.code_box, replace_pos,
                                           row_line)
                steps.append(step)
            else:
                new_part = CodePart(part.token, '')
                current_parts.append(new_part)

                typewriter = ''
                for letter in part.text:
                    typewriter += letter
                    new_part = CodePart(part.token, typewriter)
                    current_parts[-1] = new_part
                    output_parts = deepcopy(current_parts)

                    # If not last step in animation, add a cursor to the line
                    is_last_part = (count + 1 == num_parts)
                    is_last_letter = (len(typewriter) == len(part.text))
                    if not (is_last_part and is_last_letter):
                        output_parts.append(CodePart(Token, '\u2588'))

                    row_line = CodeLine(output_parts, self.code.lexer)
                    step = steplib.ReplaceRows(self.code_box, replace_pos,
                                               row_line)
                    steps.append(step)

                    steps.append(steplib.Sleep(self.delay_until_next_letter))

        return steps
Ejemplo n.º 5
0
from unittest import TestCase

from pygments.token import Token

from purdy.parser import CodePart, CodeLine, PurdyLexer

# =============================================================================

py3_lexer = PurdyLexer.factory_from_name('py3')
bash_lexer = PurdyLexer.factory_from_name('bash')

PY_CODE_LINES = [
    CodeLine([
        CodePart(Token.Comment.Single, '# Sample Code'),
    ], py3_lexer),
    CodeLine([
        CodePart(Token.Text, ''),
    ], py3_lexer),
    CodeLine([
        CodePart(Token.Keyword, 'def'),
        CodePart(Token.Text, ' '),
        CodePart(Token.Name.Function, 'foo'),
        CodePart(Token.Punctuation, '('),
        CodePart(Token.Punctuation, ')'),
        CodePart(Token.Punctuation, ':'),
    ], py3_lexer),
    CodeLine([
        CodePart(Token.Text, '    '),
        CodePart(Token.Literal.String.Doc, '"""Multi-line'),
    ], py3_lexer),
    CodeLine([