Browse Source

Build filter methods dynamically.

tags/v0.2
Ben Kurtovic 11 years ago
parent
commit
17ac79e796
1 changed files with 31 additions and 66 deletions
  1. +31
    -66
      mwparserfromhell/wikicode.py

+ 31
- 66
mwparserfromhell/wikicode.py View File

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


from .compat import maxsize, str
from .compat import maxsize, py3k, str
from .nodes import Heading, Node, Tag, Template, Text, Wikilink from .nodes import Heading, Node, Tag, Template, Text, Wikilink
from .string_mixin import StringMixIn from .string_mixin import StringMixIn
from .utils import parse_anything from .utils import parse_anything
@@ -291,46 +291,36 @@ class Wikicode(StringMixIn):
*flags*. If *forcetype* is given, only nodes that are instances of this *flags*. If *forcetype* is given, only nodes that are instances of this
type are yielded. 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 forcetype or isinstance(node, forcetype):
if not matches or re.search(matches, str(node), flags): if not matches or re.search(matches, str(node), flags):
yield node 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, def filter(self, recursive=False, matches=None, flags=FLAGS,
forcetype=None): forcetype=None):
@@ -340,38 +330,6 @@ class Wikicode(StringMixIn):
""" """
return list(self.ifilter(recursive, matches, flags, forcetype)) 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, def get_sections(self, flat=True, matches=None, levels=None, flags=FLAGS,
include_headings=True): include_headings=True):
"""Return a list of sections within the page. """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 marker = object() # Random object we can find with certainty in a list
return "\n".join(self._get_tree(self, [], marker, 0)) return "\n".join(self._get_tree(self, [], marker, 0))

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

Loading…
Cancel
Save