# -*- coding: utf-8 -*-
# :-
# SPDX-FileCopyrightText: © 2026 Franz Glasner
# SPDX-License-Identifier: MIT
# :-
r"Sub-package for filters."""

__all__ = [
    "TokenReplaceFilter",
    "ErrorToGenericErrorTokenFilter",
]


from pygments.filter import Filter
from pygments.token import (Error, Generic, Token,
                            is_token_subtype, string_to_tokentype)


class TokenReplaceFilter(Filter):

    """Replace given fixed token types with other tokens."""

    def __init__(self, **options):
        """Specifiy the replacement options:

        :param replacements: A map from tokens to their replacements.
        :type replacements:
                dict[str | pygments.token.Token, str | pygments.token.Token]

        :param token_from:
        :type token_from: str or pygments.token.Token

        :param token_to:
        :type token_to: str or pygments.token.Token

        `token_to` is required if `token_from` is given.
        If they are given they **augment** `replacements`.

        """
        Filter.__init__(self, **options)
        self.replacements = {}
        repl = options.get("replacements")
        if repl:
            for k, v in repl.items():
                if not is_token_subtype(k, Token):
                    k = string_to_tokentype(k)
                if not is_token_subtype(v, Token):
                    v = string_to_tokentype(v)
                self.replacements[k] = v
        # The option "token_from" augments the replacements if given
        token_from = options.get("token_from", None)
        if token_from:
            if not is_token_subtype(token_from, Token):
                token_from = string_to_tokentype(token_from)
            # The option "token_to" is required if "token_from" is given
            token_to = options["token_to"]
            if not is_token_subtype(token_to, Token):
                token_to = string_to_tokentype(token_to)
            self.replacements[token_from] = token_to

    def filter(self, lexer, stream):
        for ttype, value in stream:
            yield self.replacements.get(ttype, ttype), value


class ErrorToGenericErrorTokenFilter(TokenReplaceFilter):

    """Convert all :py:class:`pygments.token.Token.Error` tokens to
    :py:class:`pygments.token.Token.Generic.Error` tokens.

    """

    def __init__(self, **options):
        options["token_from"] = Error
        options["token_to"] = Generic.Error
        TokenReplaceFilter.__init__(self, **options)
