| @@ -9,6 +9,14 @@ nodes Package | |||||
| .. autoclass:: mwparserfromhell.nodes.Node | .. autoclass:: mwparserfromhell.nodes.Node | ||||
| :special-members: | :special-members: | ||||
| :mod:`argument` Module | |||||
| ---------------------- | |||||
| .. automodule:: mwparserfromhell.nodes.argument | |||||
| :members: | |||||
| :undoc-members: | |||||
| :show-inheritance: | |||||
| :mod:`heading` Module | :mod:`heading` Module | ||||
| --------------------- | --------------------- | ||||
| @@ -34,7 +34,8 @@ from __future__ import unicode_literals | |||||
| from ..compat import str | from ..compat import str | ||||
| from ..string_mixin import StringMixIn | from ..string_mixin import StringMixIn | ||||
| __all__ = ["Node", "Text", "Heading", "HTMLEntity", "Tag", "Template"] | |||||
| __all__ = ["Node", "Text", "Argument", "Heading", "HTMLEntity", "Tag", | |||||
| "Template"] | |||||
| class Node(StringMixIn): | class Node(StringMixIn): | ||||
| """Represents the base Node type, demonstrating the methods to override. | """Represents the base Node type, demonstrating the methods to override. | ||||
| @@ -66,6 +67,7 @@ class Node(StringMixIn): | |||||
| from . import extras | from . import extras | ||||
| from .text import Text | from .text import Text | ||||
| from .argument import Argument | |||||
| from .heading import Heading | from .heading import Heading | ||||
| from .html_entity import HTMLEntity | from .html_entity import HTMLEntity | ||||
| from .tag import Tag | from .tag import Tag | ||||
| @@ -0,0 +1,69 @@ | |||||
| # -*- coding: utf-8 -*- | |||||
| # | |||||
| # Copyright (C) 2012 Ben Kurtovic <ben.kurtovic@verizon.net> | |||||
| # | |||||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||||
| # of this software and associated documentation files (the "Software"), to deal | |||||
| # in the Software without restriction, including without limitation the rights | |||||
| # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||||
| # copies of the Software, and to permit persons to whom the Software is | |||||
| # furnished to do so, subject to the following conditions: | |||||
| # | |||||
| # The above copyright notice and this permission notice shall be included in | |||||
| # all copies or substantial portions of the Software. | |||||
| # | |||||
| # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
| # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
| # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||||
| # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||
| # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||||
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||||
| # SOFTWARE. | |||||
| from __future__ import unicode_literals | |||||
| from . import Node | |||||
| from ..compat import str | |||||
| from ..utils import parse_anything | |||||
| __all__ = ["Argument"] | |||||
| class Argument(Node): | |||||
| """Represents a template argument substitution, like ``{{{foo}}}``.""" | |||||
| def __init__(self, name, default=None): | |||||
| super(Argument, self).__init__() | |||||
| self._value = value | |||||
| self._default = None | |||||
| def __unicode__(self): | |||||
| start = "{{{" + unicode(self.name) | |||||
| if self.default is not None: | |||||
| return start + "|" + unicode(self.default) + "}}}" | |||||
| return start + "}}}" | |||||
| @property | |||||
| def name(self): | |||||
| """The name of the argument to substitute.""" | |||||
| return self._name | |||||
| @property | |||||
| def default(self): | |||||
| """The default value to substitute if none is passed. | |||||
| This will be ``None`` if the argument wasn't defined with one. The | |||||
| MediaWiki parser handles this by rendering the argument itself in the | |||||
| result, complete braces. To have the argument render as nothing, set | |||||
| default to ``""`` (``{{{arg}}}`` vs. ``{{{arg|}}}``). | |||||
| """ | |||||
| return self._default | |||||
| @name.setter | |||||
| def name(self, value): | |||||
| self._name = parse_anything(value) | |||||
| @default.setter | |||||
| def default(self, default): | |||||
| if default is None: | |||||
| self._default = None | |||||
| else: | |||||
| self._default = parse_anything(default) | |||||
| @@ -24,7 +24,7 @@ from __future__ import unicode_literals | |||||
| from . import tokens | from . import tokens | ||||
| from ..compat import str | from ..compat import str | ||||
| from ..nodes import Heading, HTMLEntity, Tag, Template, Text | |||||
| from ..nodes import Argument, Heading, HTMLEntity, Tag, Template, Text | |||||
| from ..nodes.extras import Attribute, Parameter | from ..nodes.extras import Attribute, Parameter | ||||
| from ..smart_list import SmartList | from ..smart_list import SmartList | ||||
| from ..wikicode import Wikicode | from ..wikicode import Wikicode | ||||
| @@ -109,6 +109,22 @@ class Builder(object): | |||||
| else: | else: | ||||
| self._write(self._handle_token(token)) | self._write(self._handle_token(token)) | ||||
| def _handle_argument(self): | |||||
| """Handle a case where an argument is at the head of the tokens.""" | |||||
| name = None | |||||
| self._push() | |||||
| while self._tokens: | |||||
| token = self._tokens.pop() | |||||
| if isinstance(token, tokens.ArgumentSeparator): | |||||
| name = self._pop() | |||||
| self._push() | |||||
| elif isinstance(token, tokens.ArgumentClose): | |||||
| if name is not None: | |||||
| return Argument(name, self._pop()) | |||||
| return Argument(self._pop()) | |||||
| else: | |||||
| self._write(self._handle_token(token)) | |||||
| def _handle_entity(self): | def _handle_entity(self): | ||||
| """Handle a case where a HTML entity is at the head of the tokens.""" | """Handle a case where a HTML entity is at the head of the tokens.""" | ||||
| token = self._tokens.pop() | token = self._tokens.pop() | ||||
| @@ -187,6 +203,8 @@ class Builder(object): | |||||
| return Text(token.text) | return Text(token.text) | ||||
| elif isinstance(token, tokens.TemplateOpen): | elif isinstance(token, tokens.TemplateOpen): | ||||
| return self._handle_template() | return self._handle_template() | ||||
| elif isinstance(token, tokens.ArgumentOpen): | |||||
| return self._handle_argument() | |||||
| elif isinstance(token, tokens.HTMLEntityStart): | elif isinstance(token, tokens.HTMLEntityStart): | ||||
| return self._handle_entity() | return self._handle_entity() | ||||
| elif isinstance(token, tokens.HeadingStart): | elif isinstance(token, tokens.HeadingStart): | ||||
| @@ -75,6 +75,10 @@ TemplateParamSeparator = make("TemplateParamSeparator") # | | |||||
| TemplateParamEquals = make("TemplateParamEquals") # = | TemplateParamEquals = make("TemplateParamEquals") # = | ||||
| TemplateClose = make("TemplateClose") # }} | TemplateClose = make("TemplateClose") # }} | ||||
| ArgumentOpen = make("ArgumentOpen") # {{{ | |||||
| ArgumentSeparator = make("ArgumentSeparator") # | | |||||
| ArgumentClose = make("ArgumentClose") # }}} | |||||
| HTMLEntityStart = make("HTMLEntityStart") # & | HTMLEntityStart = make("HTMLEntityStart") # & | ||||
| HTMLEntityNumeric = make("HTMLEntityNumeric") # # | HTMLEntityNumeric = make("HTMLEntityNumeric") # # | ||||
| HTMLEntityHex = make("HTMLEntityHex") # x | HTMLEntityHex = make("HTMLEntityHex") # x | ||||