示例#1
0
    def _inside_string(self, line):
        # Returns True if appending something to the end of this line will be
        # appending inside of a string
        last_token = line.parts[-1][0]
        if not token_is_a(last_token, String):
            return False

        # token is a String, check if multi-line
        try:
            # (position is 1-indexed, so next line in 0-index is itself)
            next_line = self.code_box.listing.lines[self.position]
        except IndexError:
            # nothing after this, so it must be a closed string
            return False

        last_token_next_line = next_line.parts[0][0]
        if not token_is_a(last_token_next_line, String):
            # next token is not a string, must be a closed string
            return False

        # if you get here we are a String and we have a String as the next
        # line, this could be because we're inside a multi-line string or
        # because the code has two doc strings back-to-back, this is the worst
        # case scenario, loop through the code and count String openers that
        # are the same as this one, if odd number, we're inside a string
        inside = False
        for line in self.code_box.listing.lines[0:self.position]:
            for part in line.parts:
                if part.token == last_token:
                    inside = not inside

        return inside
示例#2
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)
示例#3
0
    def test_tokens(self):

        #--- Test token_is_a()
        self.assertTrue(token_is_a(Token, Token))
        self.assertTrue(token_is_a(Token.Name.Function, Token.Name))
        self.assertFalse(token_is_a(Token.Name.Function, Token.Keyword))

        #--- Test token_ancestor()
        token = token_ancestor(Token.Name.Function, [Token.Name.Function])
        self.assertEqual(Token.Name.Function, token)

        token = token_ancestor(Token.Name.Function, [Token.Name])
        self.assertEqual(Token.Name, token)

        token = token_ancestor(Token.Text, [Token.Name])
        self.assertEqual(Token, token)
示例#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