Просмотр исходного кода

Add keep_template_params to Wikicode.strip_code (#175)

tags/v0.5
Ben Kurtovic 9 лет назад
Родитель
Сommit
68ded2f890
22 измененных файлов: 82 добавлений и 64 удалений
  1. +2
    -0
      CHANGELOG
  2. +2
    -0
      docs/changelog.rst
  3. +1
    -1
      mwparserfromhell/nodes/__init__.py
  4. +2
    -2
      mwparserfromhell/nodes/argument.py
  5. +3
    -3
      mwparserfromhell/nodes/external_link.py
  6. +2
    -2
      mwparserfromhell/nodes/heading.py
  7. +2
    -2
      mwparserfromhell/nodes/html_entity.py
  8. +2
    -2
      mwparserfromhell/nodes/tag.py
  9. +6
    -0
      mwparserfromhell/nodes/template.py
  10. +1
    -1
      mwparserfromhell/nodes/text.py
  11. +3
    -3
      mwparserfromhell/nodes/wikilink.py
  12. +15
    -5
      mwparserfromhell/wikicode.py
  13. +3
    -5
      tests/test_argument.py
  14. +1
    -3
      tests/test_comment.py
  15. +5
    -6
      tests/test_external_link.py
  16. +1
    -3
      tests/test_heading.py
  17. +7
    -7
      tests/test_html_entity.py
  18. +4
    -5
      tests/test_tag.py
  19. +13
    -6
      tests/test_template.py
  20. +1
    -3
      tests/test_text.py
  21. +4
    -1
      tests/test_wikicode.py
  22. +2
    -4
      tests/test_wikilink.py

+ 2
- 0
CHANGELOG Просмотреть файл

@@ -2,6 +2,8 @@ v0.5 (unreleased):


- Made Template.remove(keep_field=True) behave more reasonably when the - Made Template.remove(keep_field=True) behave more reasonably when the
parameter is already empty. parameter is already empty.
- Added the keep_template_params argument to Wikicode.strip_code(). If True,
then template parameters will be preserved in the output.
- Wikicode objects can now be pickled properly (fixed infinite recursion error - Wikicode objects can now be pickled properly (fixed infinite recursion error
on incompletely-constructed StringMixIn subclasses). on incompletely-constructed StringMixIn subclasses).
- Fixed Wikicode.matches()'s behavior on iterables besides lists and tuples. - Fixed Wikicode.matches()'s behavior on iterables besides lists and tuples.


+ 2
- 0
docs/changelog.rst Просмотреть файл

@@ -9,6 +9,8 @@ Unreleased


- Made :meth:`Template.remove(keep_field=True) <.Template.remove>` behave more - Made :meth:`Template.remove(keep_field=True) <.Template.remove>` behave more
reasonably when the parameter is already empty. reasonably when the parameter is already empty.
- Added the *keep_template_params* argument to :meth:`.Wikicode.strip_code`.
If *True*, then template parameters will be preserved in the output.
- :class:`.Wikicode` objects can now be pickled properly (fixed infinite - :class:`.Wikicode` objects can now be pickled properly (fixed infinite
recursion error on incompletely-constructed :class:`.StringMixIn` recursion error on incompletely-constructed :class:`.StringMixIn`
subclasses). subclasses).


+ 1
- 1
mwparserfromhell/nodes/__init__.py Просмотреть файл

@@ -58,7 +58,7 @@ class Node(StringMixIn):
return return
yield # pragma: no cover (this is a generator that yields nothing) yield # pragma: no cover (this is a generator that yields nothing)


def __strip__(self, normalize, collapse):
def __strip__(self, **kwargs):
return None return None


def __showtree__(self, write, get, mark): def __showtree__(self, write, get, mark):


+ 2
- 2
mwparserfromhell/nodes/argument.py Просмотреть файл

@@ -47,9 +47,9 @@ class Argument(Node):
if self.default is not None: if self.default is not None:
yield self.default yield self.default


def __strip__(self, normalize, collapse):
def __strip__(self, **kwargs):
if self.default is not None: if self.default is not None:
return self.default.strip_code(normalize, collapse)
return self.default.strip_code(**kwargs)
return None return None


def __showtree__(self, write, get, mark): def __showtree__(self, write, get, mark):


+ 3
- 3
mwparserfromhell/nodes/external_link.py Просмотреть файл

@@ -49,12 +49,12 @@ class ExternalLink(Node):
if self.title is not None: if self.title is not None:
yield self.title yield self.title


def __strip__(self, normalize, collapse):
def __strip__(self, **kwargs):
if self.brackets: if self.brackets:
if self.title: if self.title:
return self.title.strip_code(normalize, collapse)
return self.title.strip_code(**kwargs)
return None return None
return self.url.strip_code(normalize, collapse)
return self.url.strip_code(**kwargs)


def __showtree__(self, write, get, mark): def __showtree__(self, write, get, mark):
if self.brackets: if self.brackets:


+ 2
- 2
mwparserfromhell/nodes/heading.py Просмотреть файл

@@ -42,8 +42,8 @@ class Heading(Node):
def __children__(self): def __children__(self):
yield self.title yield self.title


def __strip__(self, normalize, collapse):
return self.title.strip_code(normalize, collapse)
def __strip__(self, **kwargs):
return self.title.strip_code(**kwargs)


def __showtree__(self, write, get, mark): def __showtree__(self, write, get, mark):
write("=" * self.level) write("=" * self.level)


+ 2
- 2
mwparserfromhell/nodes/html_entity.py Просмотреть файл

@@ -58,8 +58,8 @@ class HTMLEntity(Node):
return "&#{0}{1};".format(self.hex_char, self.value) return "&#{0}{1};".format(self.hex_char, self.value)
return "&#{0};".format(self.value) return "&#{0};".format(self.value)


def __strip__(self, normalize, collapse):
if normalize:
def __strip__(self, **kwargs):
if kwargs.get("normalize"):
return self.normalize() return self.normalize()
return self return self




+ 2
- 2
mwparserfromhell/nodes/tag.py Просмотреть файл

@@ -98,9 +98,9 @@ class Tag(Node):
if not self.self_closing and not self.wiki_markup and self.closing_tag: if not self.self_closing and not self.wiki_markup and self.closing_tag:
yield self.closing_tag yield self.closing_tag


def __strip__(self, normalize, collapse):
def __strip__(self, **kwargs):
if self.contents and is_visible(self.tag): if self.contents and is_visible(self.tag):
return self.contents.strip_code(normalize, collapse)
return self.contents.strip_code(**kwargs)
return None return None


def __showtree__(self, write, get, mark): def __showtree__(self, write, get, mark):


+ 6
- 0
mwparserfromhell/nodes/template.py Просмотреть файл

@@ -58,6 +58,12 @@ class Template(Node):
yield param.name yield param.name
yield param.value yield param.value


def __strip__(self, **kwargs):
if kwargs.get("keep_template_params"):
parts = [param.value.strip_code(**kwargs) for param in self.params]
return " ".join(part for part in parts if part)
return None

def __showtree__(self, write, get, mark): def __showtree__(self, write, get, mark):
write("{{") write("{{")
get(self.name) get(self.name)


+ 1
- 1
mwparserfromhell/nodes/text.py Просмотреть файл

@@ -37,7 +37,7 @@ class Text(Node):
def __unicode__(self): def __unicode__(self):
return self.value return self.value


def __strip__(self, normalize, collapse):
def __strip__(self, **kwargs):
return self return self


def __showtree__(self, write, get, mark): def __showtree__(self, write, get, mark):


+ 3
- 3
mwparserfromhell/nodes/wikilink.py Просмотреть файл

@@ -46,10 +46,10 @@ class Wikilink(Node):
if self.text is not None: if self.text is not None:
yield self.text yield self.text


def __strip__(self, normalize, collapse):
def __strip__(self, **kwargs):
if self.text is not None: if self.text is not None:
return self.text.strip_code(normalize, collapse)
return self.title.strip_code(normalize, collapse)
return self.text.strip_code(**kwargs)
return self.title.strip_code(**kwargs)


def __showtree__(self, write, get, mark): def __showtree__(self, write, get, mark):
write("[[") write("[[")


+ 15
- 5
mwparserfromhell/wikicode.py Просмотреть файл

@@ -531,23 +531,33 @@ class Wikicode(StringMixIn):
# Ensure that earlier sections are earlier in the returned list: # Ensure that earlier sections are earlier in the returned list:
return [section for i, section in sorted(sections)] return [section for i, section in sorted(sections)]


def strip_code(self, normalize=True, collapse=True):
def strip_code(self, normalize=True, collapse=True,
keep_template_params=False):
"""Return a rendered string without unprintable code such as templates. """Return a rendered string without unprintable code such as templates.


The way a node is stripped is handled by the The way a node is stripped is handled by the
:meth:`~.Node.__strip__` method of :class:`.Node` objects, which :meth:`~.Node.__strip__` method of :class:`.Node` objects, which
generally return a subset of their nodes or ``None``. For example, generally return a subset of their nodes or ``None``. For example,
templates and tags are removed completely, links are stripped to just templates and tags are removed completely, links are stripped to just
their display part, headings are stripped to just their title. If
*normalize* is ``True``, various things may be done to strip code
their display part, headings are stripped to just their title.

If *normalize* is ``True``, various things may be done to strip code
further, such as converting HTML entities like ``&Sigma;``, ``&#931;``, further, such as converting HTML entities like ``&Sigma;``, ``&#931;``,
and ``&#x3a3;`` to ``Σ``. If *collapse* is ``True``, we will try to and ``&#x3a3;`` to ``Σ``. If *collapse* is ``True``, we will try to
remove excess whitespace as well (three or more newlines are converted remove excess whitespace as well (three or more newlines are converted
to two, for example).
to two, for example). If *keep_template_params* is ``True``, then
template parameters will be preserved in the output (normally, they are
removed completely).
""" """
kwargs = {
"normalize": normalize,
"collapse": collapse,
"keep_template_params": keep_template_params
}

nodes = [] nodes = []
for node in self.nodes: for node in self.nodes:
stripped = node.__strip__(normalize, collapse)
stripped = node.__strip__(**kwargs)
if stripped: if stripped:
nodes.append(str(stripped)) nodes.append(str(stripped))




+ 3
- 5
tests/test_argument.py Просмотреть файл

@@ -56,12 +56,10 @@ class TestArgument(TreeEqualityTestCase):


def test_strip(self): def test_strip(self):
"""test Argument.__strip__()""" """test Argument.__strip__()"""
node = Argument(wraptext("foobar"))
node1 = Argument(wraptext("foobar"))
node2 = Argument(wraptext("foo"), wraptext("bar")) node2 = Argument(wraptext("foo"), wraptext("bar"))
for a in (True, False):
for b in (True, False):
self.assertIs(None, node.__strip__(a, b))
self.assertEqual("bar", node2.__strip__(a, b))
self.assertIs(None, node1.__strip__())
self.assertEqual("bar", node2.__strip__())


def test_showtree(self): def test_showtree(self):
"""test Argument.__showtree__()""" """test Argument.__showtree__()"""


+ 1
- 3
tests/test_comment.py Просмотреть файл

@@ -49,9 +49,7 @@ class TestComment(TreeEqualityTestCase):
def test_strip(self): def test_strip(self):
"""test Comment.__strip__()""" """test Comment.__strip__()"""
node = Comment("foobar") node = Comment("foobar")
for a in (True, False):
for b in (True, False):
self.assertIs(None, node.__strip__(a, b))
self.assertIs(None, node.__strip__())


def test_showtree(self): def test_showtree(self):
"""test Comment.__showtree__()""" """test Comment.__showtree__()"""


+ 5
- 6
tests/test_external_link.py Просмотреть файл

@@ -66,12 +66,11 @@ class TestExternalLink(TreeEqualityTestCase):
node2 = ExternalLink(wraptext("http://example.com")) node2 = ExternalLink(wraptext("http://example.com"))
node3 = ExternalLink(wraptext("http://example.com"), wrap([])) node3 = ExternalLink(wraptext("http://example.com"), wrap([]))
node4 = ExternalLink(wraptext("http://example.com"), wraptext("Link")) node4 = ExternalLink(wraptext("http://example.com"), wraptext("Link"))
for a in (True, False):
for b in (True, False):
self.assertEqual("http://example.com", node1.__strip__(a, b))
self.assertEqual(None, node2.__strip__(a, b))
self.assertEqual(None, node3.__strip__(a, b))
self.assertEqual("Link", node4.__strip__(a, b))

self.assertEqual("http://example.com", node1.__strip__())
self.assertEqual(None, node2.__strip__())
self.assertEqual(None, node3.__strip__())
self.assertEqual("Link", node4.__strip__())


def test_showtree(self): def test_showtree(self):
"""test ExternalLink.__showtree__()""" """test ExternalLink.__showtree__()"""


+ 1
- 3
tests/test_heading.py Просмотреть файл

@@ -52,9 +52,7 @@ class TestHeading(TreeEqualityTestCase):
def test_strip(self): def test_strip(self):
"""test Heading.__strip__()""" """test Heading.__strip__()"""
node = Heading(wraptext("foobar"), 3) node = Heading(wraptext("foobar"), 3)
for a in (True, False):
for b in (True, False):
self.assertEqual("foobar", node.__strip__(a, b))
self.assertEqual("foobar", node.__strip__())


def test_showtree(self): def test_showtree(self):
"""test Heading.__showtree__()""" """test Heading.__showtree__()"""


+ 7
- 7
tests/test_html_entity.py Просмотреть файл

@@ -57,13 +57,13 @@ class TestHTMLEntity(TreeEqualityTestCase):
node1 = HTMLEntity("nbsp", named=True, hexadecimal=False) node1 = HTMLEntity("nbsp", named=True, hexadecimal=False)
node2 = HTMLEntity("107", named=False, hexadecimal=False) node2 = HTMLEntity("107", named=False, hexadecimal=False)
node3 = HTMLEntity("e9", named=False, hexadecimal=True) node3 = HTMLEntity("e9", named=False, hexadecimal=True)
for a in (True, False):
self.assertEqual("\xa0", node1.__strip__(True, a))
self.assertEqual("&nbsp;", node1.__strip__(False, a))
self.assertEqual("k", node2.__strip__(True, a))
self.assertEqual("&#107;", node2.__strip__(False, a))
self.assertEqual("é", node3.__strip__(True, a))
self.assertEqual("&#xe9;", node3.__strip__(False, a))
self.assertEqual("\xa0", node1.__strip__(normalize=True))
self.assertEqual("&nbsp;", node1.__strip__(normalize=False))
self.assertEqual("k", node2.__strip__(normalize=True))
self.assertEqual("&#107;", node2.__strip__(normalize=False))
self.assertEqual("é", node3.__strip__(normalize=True))
self.assertEqual("&#xe9;", node3.__strip__(normalize=False))


def test_showtree(self): def test_showtree(self):
"""test HTMLEntity.__showtree__()""" """test HTMLEntity.__showtree__()"""


+ 4
- 5
tests/test_tag.py Просмотреть файл

@@ -103,11 +103,10 @@ class TestTag(TreeEqualityTestCase):
node1 = Tag(wraptext("i"), wraptext("foobar")) node1 = Tag(wraptext("i"), wraptext("foobar"))
node2 = Tag(wraptext("math"), wraptext("foobar")) node2 = Tag(wraptext("math"), wraptext("foobar"))
node3 = Tag(wraptext("br"), self_closing=True) node3 = Tag(wraptext("br"), self_closing=True)
for a in (True, False):
for b in (True, False):
self.assertEqual("foobar", node1.__strip__(a, b))
self.assertEqual(None, node2.__strip__(a, b))
self.assertEqual(None, node3.__strip__(a, b))

self.assertEqual("foobar", node1.__strip__())
self.assertEqual(None, node2.__strip__())
self.assertEqual(None, node3.__strip__())


def test_showtree(self): def test_showtree(self):
"""test Tag.__showtree__()""" """test Tag.__showtree__()"""


+ 13
- 6
tests/test_template.py Просмотреть файл

@@ -67,12 +67,19 @@ class TestTemplate(TreeEqualityTestCase):
def test_strip(self): def test_strip(self):
"""test Template.__strip__()""" """test Template.__strip__()"""
node1 = Template(wraptext("foobar")) node1 = Template(wraptext("foobar"))
node2 = Template(wraptext("foo"),
[pgenh("1", "bar"), pgens("abc", "def")])
for a in (True, False):
for b in (True, False):
self.assertEqual(None, node1.__strip__(a, b))
self.assertEqual(None, node2.__strip__(a, b))
node2 = Template(wraptext("foo"), [
pgenh("1", "bar"), pgens("foo", ""), pgens("abc", "def")])
node3 = Template(wraptext("foo"), [
pgenh("1", "foo"),
Parameter(wraptext("2"), wrap([Template(wraptext("hello"))]),
showkey=False),
pgenh("3", "bar")])

self.assertEqual(None, node1.__strip__(keep_template_params=False))
self.assertEqual(None, node2.__strip__(keep_template_params=False))
self.assertEqual("", node1.__strip__(keep_template_params=True))
self.assertEqual("bar def", node2.__strip__(keep_template_params=True))
self.assertEqual("foo bar", node3.__strip__(keep_template_params=True))


def test_showtree(self): def test_showtree(self):
"""test Template.__showtree__()""" """test Template.__showtree__()"""


+ 1
- 3
tests/test_text.py Просмотреть файл

@@ -49,9 +49,7 @@ class TestText(unittest.TestCase):
def test_strip(self): def test_strip(self):
"""test Text.__strip__()""" """test Text.__strip__()"""
node = Text("foobar") node = Text("foobar")
for a in (True, False):
for b in (True, False):
self.assertIs(node, node.__strip__(a, b))
self.assertIs(node, node.__strip__())


def test_showtree(self): def test_showtree(self):
"""test Text.__showtree__()""" """test Text.__showtree__()"""


+ 4
- 1
tests/test_wikicode.py Просмотреть файл

@@ -433,7 +433,7 @@ class TestWikicode(TreeEqualityTestCase):
"""test Wikicode.strip_code()""" """test Wikicode.strip_code()"""
# Since individual nodes have test cases for their __strip__ methods, # Since individual nodes have test cases for their __strip__ methods,
# we're only going to do an integration test: # we're only going to do an integration test:
code = parse("Foo [[bar]]\n\n{{baz}}\n\n[[a|b]] &Sigma;")
code = parse("Foo [[bar]]\n\n{{baz|hello}}\n\n[[a|b]] &Sigma;")
self.assertEqual("Foo bar\n\nb Σ", self.assertEqual("Foo bar\n\nb Σ",
code.strip_code(normalize=True, collapse=True)) code.strip_code(normalize=True, collapse=True))
self.assertEqual("Foo bar\n\n\n\nb Σ", self.assertEqual("Foo bar\n\n\n\nb Σ",
@@ -442,6 +442,9 @@ class TestWikicode(TreeEqualityTestCase):
code.strip_code(normalize=False, collapse=True)) code.strip_code(normalize=False, collapse=True))
self.assertEqual("Foo bar\n\n\n\nb &Sigma;", self.assertEqual("Foo bar\n\n\n\nb &Sigma;",
code.strip_code(normalize=False, collapse=False)) code.strip_code(normalize=False, collapse=False))
self.assertEqual("Foo bar\n\nhello\n\nb Σ",
code.strip_code(normalize=True, collapse=True,
keep_template_params=True))


def test_get_tree(self): def test_get_tree(self):
"""test Wikicode.get_tree()""" """test Wikicode.get_tree()"""


+ 2
- 4
tests/test_wikilink.py Просмотреть файл

@@ -58,10 +58,8 @@ class TestWikilink(TreeEqualityTestCase):
"""test Wikilink.__strip__()""" """test Wikilink.__strip__()"""
node = Wikilink(wraptext("foobar")) node = Wikilink(wraptext("foobar"))
node2 = Wikilink(wraptext("foo"), wraptext("bar")) node2 = Wikilink(wraptext("foo"), wraptext("bar"))
for a in (True, False):
for b in (True, False):
self.assertEqual("foobar", node.__strip__(a, b))
self.assertEqual("bar", node2.__strip__(a, b))
self.assertEqual("foobar", node.__strip__())
self.assertEqual("bar", node2.__strip__())


def test_showtree(self): def test_showtree(self):
"""test Wikilink.__showtree__()""" """test Wikilink.__showtree__()"""


Загрузка…
Отмена
Сохранить