浏览代码

Build filter methods dynamically.

tags/v0.2
Ben Kurtovic 11 年前
父节点
当前提交
17ac79e796
共有 1 个文件被更改,包括 31 次插入66 次删除
  1. +31
    -66
      mwparserfromhell/wikicode.py

+ 31
- 66
mwparserfromhell/wikicode.py 查看文件

@@ -23,7 +23,7 @@
from __future__ import unicode_literals
import re

from .compat import maxsize, str
from .compat import maxsize, py3k, str
from .nodes import Heading, Node, Tag, Template, Text, Wikilink
from .string_mixin import StringMixIn
from .utils import parse_anything
@@ -291,46 +291,36 @@ class Wikicode(StringMixIn):
*flags*. If *forcetype* is given, only nodes that are instances of this
type are yielded.
"""
if recursive:
nodes = self._get_all_nodes(self)
else:
nodes = self.nodes
for node in nodes:
for node in (self._get_all_nodes(self) if recursive else self.nodes):
if not forcetype or isinstance(node, forcetype):
if not matches or re.search(matches, str(node), flags):
yield node

def ifilter_links(self, recursive=False, matches=None, flags=FLAGS):
"""Iterate over wikilink nodes.

This is equivalent to :py:meth:`ifilter` with *forcetype* set to
:py:class:`~.Wikilink`.
"""
return self.ifilter(recursive, matches, flags, forcetype=Wikilink)

def ifilter_templates(self, recursive=False, matches=None, flags=FLAGS):
"""Iterate over template nodes.

This is equivalent to :py:meth:`ifilter` with *forcetype* set to
:py:class:`~.Template`.
"""
return self.filter(recursive, matches, flags, forcetype=Template)

def ifilter_text(self, recursive=False, matches=None, flags=FLAGS):
"""Iterate over text nodes.

This is equivalent to :py:meth:`ifilter` with *forcetype* set to
:py:class:`~.nodes.Text`.
@classmethod
def _build_filter_methods(cls, meths):
"""Given a dict of Node types, build corresponding i?filter shortcuts.

The dict should be given as keys storing the method's base name paired
with values storing the corresponding :py:class:`~.Node` type. For
example, the dict may contain the pair ``("templates", Template)``,
which will produce the methods :py:meth:`ifilter_templates` and
:py:meth:`filter_templates`, which are shortcuts for
:py:meth:`ifilter(forcetype=Template) <ifilter>` and
:py:meth:`filter(forcetype=Template) <filter>`, respectively. These
shortcuts are added to the class itself, with an appropriate docstring.
"""
return self.filter(recursive, matches, flags, forcetype=Text)

def ifilter_tags(self, recursive=False, matches=None, flags=FLAGS):
"""Iterate over tag nodes.
doc = """Iterate over {0}.

This is equivalent to :py:meth:`ifilter` with *forcetype* set to
:py:class:`~.Tag`.
This is equivalent to :py:meth:`{1}` with *forcetype* set to
:py:class:`~.{2}`.
"""
return self.ifilter(recursive, matches, flags, forcetype=Tag)
for name, forcetype in (meths.items() if py3k else meths.iteritems()):
ifil = lambda self, **kw: self.ifilter(forcetype=forcetype, **kw)
fil = lambda self, **kw: self.filter(forcetype=forcetype, **kw)
ifil.__doc__ = doc.format(name, "ifilter", forcetype)
fil.__doc__ = doc.format(name, "filter", forcetype)
setattr(cls, "ifilter_" + name, ifil)
setattr(cls, "filter_" + name, fil)

def filter(self, recursive=False, matches=None, flags=FLAGS,
forcetype=None):
@@ -340,38 +330,6 @@ class Wikicode(StringMixIn):
"""
return list(self.ifilter(recursive, matches, flags, forcetype))

def filter_links(self, recursive=False, matches=None, flags=FLAGS):
"""Return a list of wikilink nodes.

This is equivalent to calling :py:func:`list` on
:py:meth:`ifilter_links`.
"""
return list(self.ifilter_links(recursive, matches, flags))

def filter_templates(self, recursive=False, matches=None, flags=FLAGS):
"""Return a list of template nodes.

This is equivalent to calling :py:func:`list` on
:py:meth:`ifilter_templates`.
"""
return list(self.ifilter_templates(recursive, matches, flags))

def filter_text(self, recursive=False, matches=None, flags=FLAGS):
"""Return a list of text nodes.

This is equivalent to calling :py:func:`list` on
:py:meth:`ifilter_text`.
"""
return list(self.ifilter_text(recursive, matches, flags))

def filter_tags(self, recursive=False, matches=None, flags=FLAGS):
"""Return a list of tag nodes.

This is equivalent to calling :py:func:`list` on
:py:meth:`ifilter_tags`.
"""
return list(self.ifilter_tags(recursive, matches, flags))

def get_sections(self, flat=True, matches=None, levels=None, flags=FLAGS,
include_headings=True):
"""Return a list of sections within the page.
@@ -470,3 +428,10 @@ class Wikicode(StringMixIn):
"""
marker = object() # Random object we can find with certainty in a list
return "\n".join(self._get_tree(self, [], marker, 0))

Wikicode._build_filter_methods({
"links": Wikilink,
"templates": Template,
"text": Text,
"tag": Tag
})

正在加载...
取消
保存