@@ -29,5 +29,7 @@ class Node(StringMixIn): | |||||
from mwparserfromhell.nodes import extras | from mwparserfromhell.nodes import extras | ||||
from mwparserfromhell.nodes.text import Text | from mwparserfromhell.nodes.text import Text | ||||
from mwparserfromhell.nodes.heading import Heading | |||||
from mwparserfromhell.nodes.html_entity import HTMLEntity | from mwparserfromhell.nodes.html_entity import HTMLEntity | ||||
from mwparserfromhell.nodes.tag import Tag | |||||
from mwparserfromhell.nodes.template import Template | from mwparserfromhell.nodes.template import Template |
@@ -20,4 +20,5 @@ | |||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
# SOFTWARE. | # SOFTWARE. | ||||
from mwparserfromhell.nodes.extras.attribute import Attribute | |||||
from mwparserfromhell.nodes.extras.parameter import Parameter | from mwparserfromhell.nodes.extras.parameter import Parameter |
@@ -0,0 +1,50 @@ | |||||
# -*- 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 mwparserfromhell.string_mixin import StringMixIn | |||||
__all__ = ["Attribute"] | |||||
class Attribute(StringMixIn): | |||||
def __init__(self, name, value=None, quoted=True): | |||||
self._name = name | |||||
self._value = value | |||||
self._quoted = quoted | |||||
def __unicode__(self): | |||||
if self.value: | |||||
if self.quoted: | |||||
return unicode(self.name) + '="' + unicode(self.value) + '"' | |||||
return unicode(self.name) + "=" + unicode(self.value) | |||||
return unicode(self.name) | |||||
@property | |||||
def name(self): | |||||
return self._name | |||||
@property | |||||
def value(self): | |||||
return self._value | |||||
@property | |||||
def quoted(self): | |||||
return self._quoted |
@@ -26,7 +26,7 @@ from mwparserfromhell.utils import parse_anything | |||||
__all__ = ["Parameter"] | __all__ = ["Parameter"] | ||||
class Parameter(StringMixIn): | class Parameter(StringMixIn): | ||||
def __init__(self, name, value=None, showkey=True): | |||||
def __init__(self, name, value, showkey=True): | |||||
self._name = name | self._name = name | ||||
self._value = value | self._value = value | ||||
self._showkey = showkey | self._showkey = showkey | ||||
@@ -0,0 +1,41 @@ | |||||
# -*- 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 mwparserfromhell.nodes import Node | |||||
__all__ = ["Heading"] | |||||
class Heading(Node): | |||||
def __init__(self, title, level): | |||||
self._title = title | |||||
self._level = level | |||||
def __unicode__(self): | |||||
return ("=" * self.level) + self.title + ("=" * self.level) | |||||
@property | |||||
def title(self): | |||||
return self._title | |||||
@property | |||||
def level(self): | |||||
return self._level |
@@ -0,0 +1,98 @@ | |||||
# -*- 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 mwparserfromhell.nodes import Node | |||||
from mwparserfromhell.nodes.extras import Attribute | |||||
__all__ = ["Tag"] | |||||
class Tag(Node): | |||||
TAG_UNKNOWN = 0 | |||||
TAG_BOLD = 1 | |||||
TAG_ITALIC = 2 | |||||
TAG_REF | |||||
TAG_MISC_HTML = 99 | |||||
TAGS_VISIBLE = [] | |||||
TAGS_INVISIBLE = [] | |||||
def __init__(self, type_, tag, contents, attrs=None, showtag=True, | |||||
self_closing=False, open_padding=0, close_padding=0): | |||||
self._type = type_ | |||||
self._tag = tag | |||||
self._contents = contents | |||||
if attrs: | |||||
self._attrs = attrs | |||||
else: | |||||
self._attrs = [] | |||||
self._showtag = showtag | |||||
self._self_closing = self_closing | |||||
self._open_padding = open_padding | |||||
self._close_padding = close_padding | |||||
def __unicode__(self): | |||||
if not self.showtag: | |||||
raise NotImplementedError() | |||||
result = "<" + unicode(self.tag) | |||||
if self.attrs: | |||||
result += " " + u" ".join([unicode(attr) for attr in self.attrs]) | |||||
if self.self_closing: | |||||
result += " " * self.open_padding + "/>" | |||||
else: | |||||
result += " " * self.open_padding + ">" + unicode(self.contents) | |||||
result += "</" + unicode(self.tag) + " " * self.close_padding + ">" | |||||
return result | |||||
@property | |||||
def type(self): | |||||
return self._type | |||||
@property | |||||
def tag(self): | |||||
return self._tag | |||||
@property | |||||
def contents(self): | |||||
return self._contents | |||||
@property | |||||
def attrs(self): | |||||
return self._attrs | |||||
@property | |||||
def showtag(self): | |||||
return self._showtag | |||||
@property | |||||
def self_closing(self): | |||||
return self._self_closing | |||||
@property | |||||
def open_padding(self): | |||||
return self._open_padding | |||||
@property | |||||
def close_padding(self): | |||||
return self._close_padding |
@@ -22,7 +22,9 @@ | |||||
import re | import re | ||||
from mwparserfromhell.nodes import HTMLEntity, Node, Template, Text | |||||
from mwparserfromhell.nodes import ( | |||||
Heading, HTMLEntity, Node, Tag, Template, Text | |||||
) | |||||
from mwparserfromhell.string_mixin import StringMixIn | from mwparserfromhell.string_mixin import StringMixIn | ||||
from mwparserfromhell.utils import parse_anything | from mwparserfromhell.utils import parse_anything | ||||
@@ -39,7 +41,22 @@ class Wikicode(StringMixIn): | |||||
def _iterate_over_children(self, node): | def _iterate_over_children(self, node): | ||||
yield (None, node) | yield (None, node) | ||||
if isinstance(node, Template): | |||||
if isinstance(node, Heading): | |||||
for child in self._get_all_nodes(node.title): | |||||
yield (node.title, child) | |||||
elif isinstance(node, Tag): | |||||
if node.showtag: | |||||
for child in self._get_all_nodes(node.tag): | |||||
yield (node.tag, tag) | |||||
for attr in node.attrs: | |||||
for child in self._get_all_nodes(attr.name): | |||||
yield (attr.name, child) | |||||
if attr.value: | |||||
for child in self._get_all_nodes(attr.value): | |||||
yield (attr.value, child) | |||||
for child in self._get_all_nodes(node.contents): | |||||
yield (node.contents, child) | |||||
elif isinstance(node, Template): | |||||
for child in self._get_all_nodes(node.name): | for child in self._get_all_nodes(node.name): | ||||
yield (node.name, child) | yield (node.name, child) | ||||
for param in node.params: | for param in node.params: | ||||
@@ -103,11 +120,38 @@ class Wikicode(StringMixIn): | |||||
last = lines.pop() | last = lines.pop() | ||||
lines.append(last + " ".join(args)) | lines.append(last + " ".join(args)) | ||||
else: | else: | ||||
lines.append(" " * indent + " ".join(args)) | |||||
lines.append(" " * 6 * indent + " ".join(args)) | |||||
for node in code.nodes: | for node in code.nodes: | ||||
if isinstance(node, Template): | |||||
write("{{", ) | |||||
if isinstance(node, Heading): | |||||
write("=" * node.level) | |||||
self._get_tree(node.title, lines, marker, indent + 1) | |||||
write("=" * node.level) | |||||
elif isinstance(node, Tag): | |||||
tagnodes = node.tag.nodes | |||||
if (not node.attrs and len(tagnodes) == 1 and | |||||
isinstance(tagnodes[0], Text)): | |||||
write("<" + unicode(tagnodes[0]) + ">") | |||||
else: | |||||
write("<") | |||||
self._get_tree(node.tag, lines, marker, indent + 1) | |||||
for attr in node.attrs: | |||||
self._get_tree(attr.name, lines, marker, indent + 1) | |||||
if not attr.value: | |||||
continue | |||||
write(" = ") | |||||
lines.append(marker) # Continue from this line | |||||
self._get_tree(attr.value, lines, marker, indent + 1) | |||||
write(">") | |||||
self._get_tree(node.contents, lines, marker, indent + 1) | |||||
if len(tagnodes) == 1 and isinstance(tagnodes[0], Text): | |||||
write("</" + unicode(tagnodes[0]) + ">") | |||||
else: | |||||
write("</") | |||||
self._get_tree(node.tag, lines, marker, indent + 1) | |||||
write(">") | |||||
elif isinstance(node, Template): | |||||
write("{{") | |||||
self._get_tree(node.name, lines, marker, indent + 1) | self._get_tree(node.name, lines, marker, indent + 1) | ||||
for param in node.params: | for param in node.params: | ||||
write(" | ") | write(" | ") | ||||
@@ -209,14 +253,20 @@ class Wikicode(StringMixIn): | |||||
def strip_code(self, normalize=True, collapse=True): | def strip_code(self, normalize=True, collapse=True): | ||||
nodes = [] | nodes = [] | ||||
for node in self.nodes: | for node in self.nodes: | ||||
if isinstance(node, Text): | |||||
nodes.append(node) | |||||
if isinstance(node, Heading): | |||||
nodes.append(child.title) | |||||
elif isinstance(node, HTMLEntity): | elif isinstance(node, HTMLEntity): | ||||
if normalize: | if normalize: | ||||
nodes.append(node.normalize()) | nodes.append(node.normalize()) | ||||
else: | else: | ||||
nodes.append(node) | nodes.append(node) | ||||
elif isinstance(node, Tag): | |||||
if node.type in node.TAGS_VISIBLE: | |||||
nodes.append(node.contents.strip_code(normalize, collapse)) | |||||
elif isinstance(node, Text): | |||||
nodes.append(node) | |||||
nodes = map(unicode, nodes) | |||||
if collapse: | if collapse: | ||||
stripped = u"".join(nodes).strip("\n") | stripped = u"".join(nodes).strip("\n") | ||||
while "\n\n\n" in stripped: | while "\n\n\n" in stripped: | ||||