| @@ -130,10 +130,10 @@ class Template(Node): | |||||
| if self.has_param(name): | if self.has_param(name): | ||||
| self.remove(name, keep_field=True) | self.remove(name, keep_field=True) | ||||
| existing = self.get(name) | 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 | nodes = existing.value.nodes | ||||
| if force_nonconformity: | if force_nonconformity: | ||||
| existing.value = value | existing.value = value | ||||
| @@ -143,10 +143,10 @@ class Template(Node): | |||||
| if showkey is None: | if showkey is None: | ||||
| try: | try: | ||||
| int(name) | |||||
| showkey = True | |||||
| int(unicode(name)) | |||||
| showkey = False # DEPENDENTS? | |||||
| except ValueError: | except ValueError: | ||||
| showkey = False | |||||
| showkey = True | |||||
| if not showkey: | if not showkey: | ||||
| self._surface_escape(value, "=") | self._surface_escape(value, "=") | ||||
| if not force_nonconformity: | if not force_nonconformity: | ||||
| @@ -35,11 +35,16 @@ class Builder(object): | |||||
| self._tokens = [] | self._tokens = [] | ||||
| self._stacks = [] | self._stacks = [] | ||||
| def _wrap(self, nodes): | |||||
| return Wikicode(SmartList(nodes)) | |||||
| def _push(self): | def _push(self): | ||||
| self._stacks.append([]) | 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): | def _write(self, item): | ||||
| self._stacks[-1].append(item) | self._stacks[-1].append(item) | ||||
| @@ -71,9 +76,10 @@ class Builder(object): | |||||
| if isinstance(token, tokens.TemplateParamSeparator): | if isinstance(token, tokens.TemplateParamSeparator): | ||||
| if not params: | if not params: | ||||
| name = self._pop() | 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()): | 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) | int_key_range.add(len(int_keys) + 1) | ||||
| params.append(param) | params.append(param) | ||||
| elif isinstance(token, tokens.TemplateClose): | elif isinstance(token, tokens.TemplateClose): | ||||
| @@ -66,7 +66,7 @@ class Tokenizer(object): | |||||
| def _verify_context(self): | def _verify_context(self): | ||||
| if self._read() is self.END: | if self._read() is self.END: | ||||
| if self._context & contexts.INSIDE_TEMPLATE: | |||||
| if self._context & contexts.TEMPLATE: | |||||
| raise BadRoute() | raise BadRoute() | ||||
| def _catch_stop(self, stop): | def _catch_stop(self, stop): | ||||
| @@ -110,6 +110,13 @@ class Tokenizer(object): | |||||
| return self._pop() | return self._pop() | ||||
| if self._read(0) == "{" and self._read(1) == "{": | if self._read(0) == "{" and self._read(1) == "{": | ||||
| self._parse_template() | 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: | else: | ||||
| self._write(tokens.Text(text=self._read())) | self._write(tokens.Text(text=self._read())) | ||||
| self._head += 1 | self._head += 1 | ||||
| @@ -81,6 +81,7 @@ class SmartList(list): | |||||
| def __iadd__(self, other): | def __iadd__(self, other): | ||||
| self.extend(other) | self.extend(other) | ||||
| return self | |||||
| def append(self, item): | def append(self, item): | ||||
| head = len(self) | head = len(self) | ||||
| @@ -221,6 +222,7 @@ class _ListProxy(list): | |||||
| def __iadd__(self, other): | def __iadd__(self, other): | ||||
| self.extend(other) | self.extend(other) | ||||
| return self | |||||
| @property | @property | ||||
| def _start(self): | def _start(self): | ||||
| @@ -22,24 +22,25 @@ | |||||
| import mwparserfromhell | import mwparserfromhell | ||||
| from .nodes import Node | from .nodes import Node | ||||
| from .smart_list import SmartList | |||||
| def parse_anything(value): | def parse_anything(value): | ||||
| wikicode = mwparserfromhell.wikicode.Wikicode | wikicode = mwparserfromhell.wikicode.Wikicode | ||||
| if isinstance(value, wikicode): | if isinstance(value, wikicode): | ||||
| return value | return value | ||||
| if isinstance(value, Node): | if isinstance(value, Node): | ||||
| return wikicode([value]) | |||||
| return wikicode(SmartList([value])) | |||||
| if isinstance(value, basestring): | if isinstance(value, basestring): | ||||
| return mwparserfromhell.parse(value) | return mwparserfromhell.parse(value) | ||||
| if isinstance(value, int): | if isinstance(value, int): | ||||
| return mwparserfromhell.parse(unicode(value)) | return mwparserfromhell.parse(unicode(value)) | ||||
| if value is None: | if value is None: | ||||
| return wikicode([]) | |||||
| return wikicode(SmartList()) | |||||
| try: | try: | ||||
| nodelist = [] | |||||
| nodelist = SmartList() | |||||
| for item in value: | for item in value: | ||||
| nodelist += parse_anything(item).nodes | nodelist += parse_anything(item).nodes | ||||
| except TypeError: | except TypeError: | ||||
| error = "Needs string, Node, Wikicode, int, None, or iterable of these, but got {0}: {1}" | 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) | return wikicode(nodelist) | ||||
| @@ -104,6 +104,10 @@ class Wikicode(StringMixIn): | |||||
| def nodes(self): | def nodes(self): | ||||
| return self._nodes | return self._nodes | ||||
| @nodes.setter | |||||
| def nodes(self, value): | |||||
| self._nodes = value | |||||
| def get(self, index): | def get(self, index): | ||||
| return self.nodes[index] | return self.nodes[index] | ||||