@@ -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] | ||||