def _make_charlist(self, tokens, tokmap, formats):
        """
        Parses the complete text and stores format for each character.

        Uses the attached lexer to parse into a list of tokens and Pygments
        token types.  Then breaks tokens into individual letters, each with a
        Spyder token type attached.  Stores this list as self._charlist.

        It's attached to the contentsChange signal of the parent QTextDocument
        so that the charlist is updated whenever the document changes.
        """

        def _get_fmt(typ):
            """Get the Spyder format code for the given Pygments token type."""
            # Exact matches first
            if typ in tokmap:
                return tokmap[typ]
            # Partial (parent-> child) matches
            for key, val in tokmap.items():
                if typ in key: # Checks if typ is a subtype of key.
                    return val

            return 'normal'

        charlist = []
        for typ, token in tokens:
            fmt = formats[_get_fmt(typ)]
            for letter in token:
                charlist.append((fmt, letter))

        return charlist
Parses the complete text and stores format for each character.

        Uses the attached lexer to parse into a list of tokens and Pygments
        token types.  Then breaks tokens into individual letters, each with a
        Spyder token type attached.  Stores this list as self._charlist.

        It's attached to the contentsChange signal of the parent QTextDocument
        so that the charlist is updated whenever the document changes.