diff --git a/CHANGELOG b/CHANGELOG
index aa8d0b5..32a14e4 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,7 +2,10 @@ v0.3 (unreleased):
- Added complete support for HTML Tags, along with appropriate unit tests. This
includes forms like [foo], , and wiki-markup tags
- like bold ('''), italics (''), and lists (''*'', ''#'', '';'' and '':'').
+ like bold ('''), italics (''), and lists (*, #, ; and :).
+- Wikicode's filter methods are now passed 'recursive=True' by default instead
+ of False. This is a breaking change if you rely on any filter() methods being
+ non-recursive by default.
- Various fixes and cleanup.
v0.2 (released June 20, 2013):
diff --git a/README.rst b/README.rst
index 26b63bb..d481700 100644
--- a/README.rst
+++ b/README.rst
@@ -60,13 +60,20 @@ For example::
>>> print template.get("eggs").value
spam
-Since every node you reach is also a ``Wikicode`` object, it's trivial to get
-nested templates::
+Since nodes can contain other nodes, getting nested templates is trivial::
+
+ >>> text = "{{foo|{{bar}}={{baz|{{spam}}}}}}"
+ >>> mwparserfromhell.parse(text).filter_templates()
+ ['{{foo|{{bar}}={{baz|{{spam}}}}}}', '{{bar}}', '{{baz|{{spam}}}}', '{{spam}}']
+
+You can also pass ``recursive=False`` to ``filter_templates()`` and explore
+templates manually. This is possible because nodes can contain additional
+``Wikicode`` objects::
>>> code = mwparserfromhell.parse("{{foo|this {{includes a|template}}}}")
- >>> print code.filter_templates()
+ >>> print code.filter_templates(recursive=False)
['{{foo|this {{includes a|template}}}}']
- >>> foo = code.filter_templates()[0]
+ >>> foo = code.filter_templates(recursive=False)[0]
>>> print foo.get(1).value
this {{includes a|template}}
>>> print foo.get(1).value.filter_templates()[0]
@@ -74,13 +81,6 @@ nested templates::
>>> print foo.get(1).value.filter_templates()[0].get(1).value
template
-Additionally, you can include nested templates in ``filter_templates()`` by
-passing ``recursive=True``::
-
- >>> text = "{{foo|{{bar}}={{baz|{{spam}}}}}}"
- >>> mwparserfromhell.parse(text).filter_templates(recursive=True)
- ['{{foo|{{bar}}={{baz|{{spam}}}}}}', '{{bar}}', '{{baz|{{spam}}}}', '{{spam}}']
-
Templates can be easily modified to add, remove, or alter params. ``Wikicode``
can also be treated like a list with ``append()``, ``insert()``, ``remove()``,
``replace()``, and more::
diff --git a/docs/changelog.rst b/docs/changelog.rst
index cf8708d..18687f0 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -10,7 +10,10 @@ Unreleased
- Added complete support for HTML :py:class:`Tags <.Tag>`, along with
appropriate unit tests. This includes forms like ``[foo]``,
````, and wiki-markup tags like bold (``'''``), italics
- (``''``), and lists (``''*''``, ``''#''``, ``'';''`` and ``'':''``).
+ (``''``), and lists (``*``, ``#``, ``;`` and ``:``).
+- :py:class:`Wikicode's <.Wikicode>` :py:meth:`.filter` methods are now passed
+ *recursive=True* by default instead of *False*. **This is a breaking change
+ if you rely on any filter() methods being non-recursive by default.**
- Various fixes and cleanup.
v0.2
diff --git a/docs/usage.rst b/docs/usage.rst
index 2fd19af..fd24a15 100644
--- a/docs/usage.rst
+++ b/docs/usage.rst
@@ -27,13 +27,20 @@ some extra methods. For example::
>>> print template.get("eggs").value
spam
-Since every node you reach is also a :py:class:`~.Wikicode` object, it's
-trivial to get nested templates::
+Since nodes can contain other nodes, getting nested templates is trivial::
+
+ >>> text = "{{foo|{{bar}}={{baz|{{spam}}}}}}"
+ >>> mwparserfromhell.parse(text).filter_templates()
+ ['{{foo|{{bar}}={{baz|{{spam}}}}}}', '{{bar}}', '{{baz|{{spam}}}}', '{{spam}}']
+
+You can also pass *recursive=False* to :py:meth:`~.filter_templates` and
+explore templates manually. This is possible because nodes can contain
+additional :py:class:`~.Wikicode` objects::
>>> code = mwparserfromhell.parse("{{foo|this {{includes a|template}}}}")
- >>> print code.filter_templates()
+ >>> print code.filter_templates(recursive=False)
['{{foo|this {{includes a|template}}}}']
- >>> foo = code.filter_templates()[0]
+ >>> foo = code.filter_templates(recursive=False)[0]
>>> print foo.get(1).value
this {{includes a|template}}
>>> print foo.get(1).value.filter_templates()[0]
@@ -41,13 +48,6 @@ trivial to get nested templates::
>>> print foo.get(1).value.filter_templates()[0].get(1).value
template
-Additionally, you can include nested templates in :py:meth:`~.filter_templates`
-by passing *recursive=True*::
-
- >>> text = "{{foo|{{bar}}={{baz|{{spam}}}}}}"
- >>> mwparserfromhell.parse(text).filter_templates(recursive=True)
- ['{{foo|{{bar}}={{baz|{{spam}}}}}}', '{{bar}}', '{{baz|{{spam}}}}', '{{spam}}']
-
Templates can be easily modified to add, remove, or alter params.
:py:class:`~.Wikicode` can also be treated like a list with
:py:meth:`~.Wikicode.append`, :py:meth:`~.Wikicode.insert`,
diff --git a/mwparserfromhell/wikicode.py b/mwparserfromhell/wikicode.py
index 4ec889e..90b5d18 100644
--- a/mwparserfromhell/wikicode.py
+++ b/mwparserfromhell/wikicode.py
@@ -309,7 +309,7 @@ class Wikicode(StringMixIn):
callback = lambda self, i: self.nodes.pop(i)
self._do_search(obj, recursive, callback, self)
- def ifilter(self, recursive=False, matches=None, flags=FLAGS,
+ def ifilter(self, recursive=True, matches=None, flags=FLAGS,
forcetype=None):
"""Iterate over nodes in our list matching certain conditions.
@@ -327,7 +327,7 @@ class Wikicode(StringMixIn):
if not matches or re.search(matches, str(node), flags):
yield node
- def filter(self, recursive=False, matches=None, flags=FLAGS,
+ def filter(self, recursive=True, matches=None, flags=FLAGS,
forcetype=None):
"""Return a list of nodes within our list matching certain conditions.
diff --git a/tests/test_docs.py b/tests/test_docs.py
index 8d95c47..5fdb520 100644
--- a/tests/test_docs.py
+++ b/tests/test_docs.py
@@ -61,30 +61,30 @@ class TestDocs(unittest.TestCase):
def test_readme_2(self):
"""test a block of example code in the README"""
+ text = "{{foo|{{bar}}={{baz|{{spam}}}}}}"
+ temps = mwparserfromhell.parse(text).filter_templates()
+ if py3k:
+ res = "['{{foo|{{bar}}={{baz|{{spam}}}}}}', '{{bar}}', '{{baz|{{spam}}}}', '{{spam}}']"
+ else:
+ res = "[u'{{foo|{{bar}}={{baz|{{spam}}}}}}', u'{{bar}}', u'{{baz|{{spam}}}}', u'{{spam}}']"
+ self.assertPrint(temps, res)
+
+ def test_readme_3(self):
+ """test a block of example code in the README"""
code = mwparserfromhell.parse("{{foo|this {{includes a|template}}}}")
if py3k:
- self.assertPrint(code.filter_templates(),
+ self.assertPrint(code.filter_templates(recursive=False),
"['{{foo|this {{includes a|template}}}}']")
else:
- self.assertPrint(code.filter_templates(),
+ self.assertPrint(code.filter_templates(recursive=False),
"[u'{{foo|this {{includes a|template}}}}']")
- foo = code.filter_templates()[0]
+ foo = code.filter_templates(recursive=False)[0]
self.assertPrint(foo.get(1).value, "this {{includes a|template}}")
self.assertPrint(foo.get(1).value.filter_templates()[0],
"{{includes a|template}}")
self.assertPrint(foo.get(1).value.filter_templates()[0].get(1).value,
"template")
- def test_readme_3(self):
- """test a block of example code in the README"""
- text = "{{foo|{{bar}}={{baz|{{spam}}}}}}"
- temps = mwparserfromhell.parse(text).filter_templates(recursive=True)
- if py3k:
- res = "['{{foo|{{bar}}={{baz|{{spam}}}}}}', '{{bar}}', '{{baz|{{spam}}}}', '{{spam}}']"
- else:
- res = "[u'{{foo|{{bar}}={{baz|{{spam}}}}}}', u'{{bar}}', u'{{baz|{{spam}}}}', u'{{spam}}']"
- self.assertPrint(temps, res)
-
def test_readme_4(self):
"""test a block of example code in the README"""
text = "{{cleanup}} '''Foo''' is a [[bar]]. {{uncategorized}}"
diff --git a/tests/test_wikicode.py b/tests/test_wikicode.py
index 8dfa655..2684414 100644
--- a/tests/test_wikicode.py
+++ b/tests/test_wikicode.py
@@ -219,11 +219,11 @@ class TestWikicode(TreeEqualityTestCase):
code = parse("a{{b}}c[[d]]{{{e}}}{{f}}[[g]]")
for func in (code.filter, ifilter(code)):
- self.assertEqual(["a", "{{b}}", "c", "[[d]]", "{{{e}}}", "{{f}}",
- "[[g]]"], func())
+ self.assertEqual(["a", "{{b}}", "b", "c", "[[d]]", "d", "{{{e}}}",
+ "e", "{{f}}", "f", "[[g]]", "g"], func())
self.assertEqual(["{{{e}}}"], func(forcetype=Argument))
self.assertIs(code.get(4), func(forcetype=Argument)[0])
- self.assertEqual(["a", "c"], func(forcetype=Text))
+ self.assertEqual(list("abcdefg"), func(forcetype=Text))
self.assertEqual([], func(forcetype=Heading))
self.assertRaises(TypeError, func, forcetype=True)
@@ -239,7 +239,7 @@ class TestWikicode(TreeEqualityTestCase):
self.assertEqual([], get_filter("html_entities"))
self.assertEqual([], get_filter("tags"))
self.assertEqual(["{{b}}", "{{f}}"], get_filter("templates"))
- self.assertEqual(["a", "c"], get_filter("text"))
+ self.assertEqual(list("abcdefg"), get_filter("text"))
self.assertEqual(["[[d]]", "[[g]]"], get_filter("wikilinks"))
code2 = parse("{{a|{{b}}|{{c|d={{f}}{{h}}}}}}")
@@ -252,13 +252,13 @@ class TestWikicode(TreeEqualityTestCase):
code3 = parse("{{foobar}}{{FOO}}{{baz}}{{bz}}")
for func in (code3.filter, ifilter(code3)):
- self.assertEqual(["{{foobar}}", "{{FOO}}"], func(matches=r"foo"))
+ self.assertEqual(["{{foobar}}", "{{FOO}}"], func(recursive=False, matches=r"foo"))
self.assertEqual(["{{foobar}}", "{{FOO}}"],
- func(matches=r"^{{foo.*?}}"))
+ func(recursive=False, matches=r"^{{foo.*?}}"))
self.assertEqual(["{{foobar}}"],
- func(matches=r"^{{foo.*?}}", flags=re.UNICODE))
- self.assertEqual(["{{baz}}", "{{bz}}"], func(matches=r"^{{b.*?z"))
- self.assertEqual(["{{baz}}"], func(matches=r"^{{b.+?z}}"))
+ func(recursive=False, matches=r"^{{foo.*?}}", flags=re.UNICODE))
+ self.assertEqual(["{{baz}}", "{{bz}}"], func(recursive=False, matches=r"^{{b.*?z"))
+ self.assertEqual(["{{baz}}"], func(recursive=False, matches=r"^{{b.+?z}}"))
self.assertEqual(["{{a|{{b}}|{{c|d={{f}}{{h}}}}}}"],
code2.filter_templates(recursive=False))