编写自己的过滤器

在版本 0.7 中添加。

编写自己的过滤器非常容易。您只需子类化 Filter 类并覆盖 filter 方法即可。此外,过滤器会使用一些关键字参数实例化,您可以使用这些参数来调整过滤器的行为。

子类化过滤器

例如,我们编写一个过滤器,将所有 Name.Function 令牌转换为普通的 Name 令牌,以使输出不那么丰富多彩。

from pygments.util import get_bool_opt
from pygments.token import Name
from pygments.filter import Filter

class UncolorFilter(Filter):

    def __init__(self, **options):
        Filter.__init__(self, **options)
        self.class_too = get_bool_opt(options, 'classtoo')

    def filter(self, lexer, stream):
        for ttype, value in stream:
            if ttype is Name.Function or (self.class_too and
                                          ttype is Name.Class):
                ttype = Name
            yield ttype, value

关于 lexer 参数的一些说明:这可能很令人困惑,因为它不需要是词法分析器实例。如果通过使用词法分析器的 add_filter() 函数添加了过滤器,则该词法分析器将为该过滤器注册。在这种情况下,lexer 将引用已注册过滤器的词法分析器。它可以用于访问传递给词法分析器的选项。因为它可能是 None,所以您在访问它时始终要检查这种情况。

使用装饰器

您还可以使用 pygments.filter 模块中的 simplefilter 装饰器

from pygments.util import get_bool_opt
from pygments.token import Name
from pygments.filter import simplefilter


@simplefilter
def uncolor(self, lexer, stream, options):
    class_too = get_bool_opt(options, 'classtoo')
    for ttype, value in stream:
        if ttype is Name.Function or (class_too and
                                      ttype is Name.Class):
            ttype = Name
        yield ttype, value

您可以通过调用 uncolor(classtoo=True) 来实例化此过滤器,就像您通过调用 UncolorFilter(classtoo=True) 来实例化先前过滤器一样。实际上,装饰器会自动确保 uncolor 是一个子类化内部过滤器类的类。类 uncolo 使用装饰的函数作为过滤方法。(这就是为什么有一个 self 参数,您可能最终不会在该方法中使用它。)