Browse Source

Implement support for Template.remove() taking Parameters as arguments.

tags/v0.3.2
Ben Kurtovic 11 years ago
parent
commit
f2442906db
1 changed files with 29 additions and 12 deletions
  1. +29
    -12
      mwparserfromhell/nodes/template.py

+ 29
- 12
mwparserfromhell/nodes/template.py View File

@@ -150,6 +150,16 @@ class Template(Node):
return False return False
return True return True


def _remove_exact(self, needle, keep_field):
"""Remove a specific parameter, *needle*, from the template."""
for i, param in enumerate(self.params):
if param is needle:
if keep_field or not self._remove_without_field(param, i):
self._blank_param_value(param.value)
else:
self.params.pop(i)
return

@property @property
def name(self): def name(self):
"""The name of the template, as a :py:class:`~.Wikicode` object.""" """The name of the template, as a :py:class:`~.Wikicode` object."""
@@ -180,7 +190,8 @@ class Template(Node):
return True return True
return False return False


has_param = lambda self, *args, **kwargs: self.has(*args, **kwargs)
has_param = lambda self, name, ignore_empty=True: \
self.has(name, ignore_empty)
has_param.__doc__ = "Alias for :py:meth:`has`." has_param.__doc__ = "Alias for :py:meth:`has`."


def get(self, name): def get(self, name):
@@ -280,8 +291,12 @@ class Template(Node):
self.params.append(param) self.params.append(param)
return param return param


def remove(self, name, keep_field=False):
"""Remove a parameter from the template whose name is *name*.
def remove(self, param, keep_field=False):
"""Remove a parameter from the template, identified by *param*.

If *param* is a :py:class:`.Parameter` object, it will be matched
exactly, otherwise it will be treated like the *name* argument to
:py:meth:`has` and :py:meth:`get`.


If *keep_field* is ``True``, we will keep the parameter's name, but If *keep_field* is ``True``, we will keep the parameter's name, but
blank its value. Otherwise, we will remove the parameter completely blank its value. Otherwise, we will remove the parameter completely
@@ -289,12 +304,14 @@ class Template(Node):
from ``{{foo|bar|baz}}`` is unsafe because ``{{foo|baz}}`` is not what from ``{{foo|bar|baz}}`` is unsafe because ``{{foo|baz}}`` is not what
we expected, so ``{{foo||baz}}`` will be produced instead). we expected, so ``{{foo||baz}}`` will be produced instead).


If the parameter shows up multiple times in the template, we will
remove all instances of it (and keep one if *keep_field* is ``True`` -
the first instance if none have dependents, otherwise the one with
dependents will be kept).
If the parameter shows up multiple times in the template and *param* is
not a :py:class:`.Parameter` object, we will remove all instances of it
(and keep only one if *keep_field* is ``True`` - the first instance if
none have dependents, otherwise the one with dependents will be kept).
""" """
name = str(name).strip()
if isinstance(param, Parameter):
return self._remove_exact(param, keep_field)
name = str(param).strip()
removed = False removed = False
to_remove = [] to_remove = []
for i, param in enumerate(self.params): for i, param in enumerate(self.params):
@@ -304,15 +321,15 @@ class Template(Node):
self._blank_param_value(param.value) self._blank_param_value(param.value)
keep_field = False keep_field = False
else: else:
to_remove.append(param)
to_remove.append(i)
else: else:
if self._remove_without_field(param, i): if self._remove_without_field(param, i):
to_remove.append(param)
to_remove.append(i)
else: else:
self._blank_param_value(param.value) self._blank_param_value(param.value)
if not removed: if not removed:
removed = True removed = True
if not removed: if not removed:
raise ValueError(name) raise ValueError(name)
for param in to_remove:
self.params.remove(param)
for i, index in enumerate(to_remove):
self.params.pop(index - i) # Note the shift when we remove a param

Loading…
Cancel
Save