From 934b1ef016e3bc062b4956184cf48026f4127a6a Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Tue, 14 Aug 2012 20:32:02 -0400 Subject: [PATCH] Fixes and improvements. --- mwparserfromhell/nodes/template.py | 14 +++++++------- mwparserfromhell/parser/builder.py | 14 ++++++++++---- mwparserfromhell/parser/tokenizer.py | 9 ++++++++- mwparserfromhell/smart_list.py | 2 ++ mwparserfromhell/utils.py | 9 +++++---- mwparserfromhell/wikicode.py | 4 ++++ 6 files changed, 36 insertions(+), 16 deletions(-) diff --git a/mwparserfromhell/nodes/template.py b/mwparserfromhell/nodes/template.py index d77388f..772a89a 100644 --- a/mwparserfromhell/nodes/template.py +++ b/mwparserfromhell/nodes/template.py @@ -130,10 +130,10 @@ class Template(Node): if self.has_param(name): self.remove(name, keep_field=True) existing = self.get(name) - if showkey is None: # Infer showkey from current value - showkey = existing.showkey - if not showkey: - self._surface_escape(value, "=") + if showkey is not None: + if not showkey: + self._surface_escape(value, "=") + existing.showkey = showkey nodes = existing.value.nodes if force_nonconformity: existing.value = value @@ -143,10 +143,10 @@ class Template(Node): if showkey is None: try: - int(name) - showkey = True + int(unicode(name)) + showkey = False # DEPENDENTS? except ValueError: - showkey = False + showkey = True if not showkey: self._surface_escape(value, "=") if not force_nonconformity: diff --git a/mwparserfromhell/parser/builder.py b/mwparserfromhell/parser/builder.py index 715aa8e..ef81083 100644 --- a/mwparserfromhell/parser/builder.py +++ b/mwparserfromhell/parser/builder.py @@ -35,11 +35,16 @@ class Builder(object): self._tokens = [] self._stacks = [] + def _wrap(self, nodes): + return Wikicode(SmartList(nodes)) + def _push(self): self._stacks.append([]) - def _pop(self): - return Wikicode(SmartList(self._stacks.pop())) + def _pop(self, wrap=True): + if wrap: + return self._wrap(self._stacks.pop()) + return self._stacks.pop() def _write(self, item): self._stacks[-1].append(item) @@ -71,9 +76,10 @@ class Builder(object): if isinstance(token, tokens.TemplateParamSeparator): if not params: name = self._pop() - param = self._handle_parameter(min(int_key_range - int_keys)) + default = self._wrap(unicode(min(int_key_range - int_keys))) + param = self._handle_parameter(default) if re.match(r"[1-9][0-9]*$", param.name.strip()): - int_keys.add(int(param.name)) + int_keys.add(int(unicode(param.name))) int_key_range.add(len(int_keys) + 1) params.append(param) elif isinstance(token, tokens.TemplateClose): diff --git a/mwparserfromhell/parser/tokenizer.py b/mwparserfromhell/parser/tokenizer.py index 260a5b1..78b6f4d 100644 --- a/mwparserfromhell/parser/tokenizer.py +++ b/mwparserfromhell/parser/tokenizer.py @@ -66,7 +66,7 @@ class Tokenizer(object): def _verify_context(self): if self._read() is self.END: - if self._context & contexts.INSIDE_TEMPLATE: + if self._context & contexts.TEMPLATE: raise BadRoute() def _catch_stop(self, stop): @@ -110,6 +110,13 @@ class Tokenizer(object): return self._pop() if self._read(0) == "{" and self._read(1) == "{": self._parse_template() + elif self._read(0) == "|" and self._context & contexts.TEMPLATE: + if self._context & contexts.TEMPLATE_NAME: + self._context ^= contexts.TEMPLATE_NAME + if self._context & contexts.TEMPLATE_PARAM_VALUE: + self._context ^= contexts.TEMPLATE_PARAM_VALUE + self._context |= contexts.TEMPLATE_PARAM_KEY + self._write(tokens.TemplateParamSeparator()) else: self._write(tokens.Text(text=self._read())) self._head += 1 diff --git a/mwparserfromhell/smart_list.py b/mwparserfromhell/smart_list.py index 855aaa2..1d64bce 100644 --- a/mwparserfromhell/smart_list.py +++ b/mwparserfromhell/smart_list.py @@ -81,6 +81,7 @@ class SmartList(list): def __iadd__(self, other): self.extend(other) + return self def append(self, item): head = len(self) @@ -221,6 +222,7 @@ class _ListProxy(list): def __iadd__(self, other): self.extend(other) + return self @property def _start(self): diff --git a/mwparserfromhell/utils.py b/mwparserfromhell/utils.py index 33084b5..9c32c10 100644 --- a/mwparserfromhell/utils.py +++ b/mwparserfromhell/utils.py @@ -22,24 +22,25 @@ import mwparserfromhell from .nodes import Node +from .smart_list import SmartList def parse_anything(value): wikicode = mwparserfromhell.wikicode.Wikicode if isinstance(value, wikicode): return value if isinstance(value, Node): - return wikicode([value]) + return wikicode(SmartList([value])) if isinstance(value, basestring): return mwparserfromhell.parse(value) if isinstance(value, int): return mwparserfromhell.parse(unicode(value)) if value is None: - return wikicode([]) + return wikicode(SmartList()) try: - nodelist = [] + nodelist = SmartList() for item in value: nodelist += parse_anything(item).nodes except TypeError: error = "Needs string, Node, Wikicode, int, None, or iterable of these, but got {0}: {1}" - raise ValueError(error.format(type(value), value)) + raise ValueError(error.format(type(value).__name__, value)) return wikicode(nodelist) diff --git a/mwparserfromhell/wikicode.py b/mwparserfromhell/wikicode.py index 7680e20..af22c24 100644 --- a/mwparserfromhell/wikicode.py +++ b/mwparserfromhell/wikicode.py @@ -104,6 +104,10 @@ class Wikicode(StringMixIn): def nodes(self): return self._nodes + @nodes.setter + def nodes(self, value): + self._nodes = value + def get(self, index): return self.nodes[index]