aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mammoth/style_reader.py46
-rw-r--r--tests/style_reader_tests.py8
2 files changed, 48 insertions, 6 deletions
diff --git a/mammoth/style_reader.py b/mammoth/style_reader.py
index 0c27bd8..7a7474f 100644
--- a/mammoth/style_reader.py
+++ b/mammoth/style_reader.py
@@ -4,19 +4,53 @@ from . import html_paths
def read_html_path(string):
- root_node = _grammar.parse(string)
- tag_names = [root_node.children[0].text]
+ path_node = _grammar.parse(string)
+ return _read_path_node(path_node)
- for choice_node in root_node.children[1].children:
- tag_names.append(choice_node.children[1].text)
+
+
+def _read_path_node(path_node):
+ elements = [
+ _read_element_node(child)
+ for child in _repeated_children_with_separator(path_node, has_whitespace=True)
+ ]
+ return html_paths.path(elements)
+
+
+def _read_element_node(node):
+ return html_paths.element(_read_tag_names_node(node))
+
+
+def _read_tag_names_node(node):
+ return [
+ child.text
+ for child in _repeated_children_with_separator(node, has_whitespace=False)
+ ]
+
+
+def _repeated_children_with_separator(node, has_whitespace):
+ yield node.children[0]
+
+ if has_whitespace:
+ sequence_node_index = 2
+ else:
+ sequence_node_index = 1
- return html_paths.path([html_paths.element(tag_names)])
+ sequence_node = node.children[sequence_node_index]
+ for child in sequence_node.children:
+ yield child.children[sequence_node_index]
-_grammar = Grammar("""
+_grammar = Grammar(r"""
+
+path = element whitespace* (">" whitespace* element)*
+
+element = tag_names
tag_names = identifier ("|" identifier)*
identifier = ~"[A-Z0-9]*"i
+whitespace = ~"\s"*
+
""")
diff --git a/tests/style_reader_tests.py b/tests/style_reader_tests.py
index 43bb3db..595ece1 100644
--- a/tests/style_reader_tests.py
+++ b/tests/style_reader_tests.py
@@ -27,3 +27,11 @@ class ReadHtmlPathTests(object):
html_paths.path([html_paths.element(["ul", "ol", "p"])]),
read_html_path("ul|ol|p")
)
+
+
+ @istest
+ def can_read_nested_elements(self):
+ assert_equal(
+ html_paths.path([html_paths.element(["ul"]), html_paths.element(["li"])]),
+ read_html_path("ul > li")
+ )