summaryrefslogtreecommitdiff
path: root/mammoth/style_reader/html_path_reader.py
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2013-12-12 22:29:02 +0000
committerMichael Williamson <mike@zwobble.org>2013-12-12 22:29:02 +0000
commit1fd31a5fa207c40aaaae74f62cc3b491f15dcd41 (patch)
tree1fe6cc83eb6ca92ccfbe1bd1c2b9941531e03ac7 /mammoth/style_reader/html_path_reader.py
parent2791c74b8c1afc1014e380111b7e7f4d4ea09539 (diff)
Move html path reading into separate module
Diffstat (limited to 'mammoth/style_reader/html_path_reader.py')
-rw-r--r--mammoth/style_reader/html_path_reader.py79
1 files changed, 79 insertions, 0 deletions
diff --git a/mammoth/style_reader/html_path_reader.py b/mammoth/style_reader/html_path_reader.py
new file mode 100644
index 0000000..0de6e8c
--- /dev/null
+++ b/mammoth/style_reader/html_path_reader.py
@@ -0,0 +1,79 @@
+from parsimonious.grammar import Grammar
+
+from .. import html_paths
+
+
+def read_html_path(string):
+ path_node = _grammar.parse(string)
+ return _read_path_node(path_node)
+
+
+
+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):
+ tag_names = _read_tag_names_node(node.children[0])
+ class_names = _read_class_names_node(node.children[1])
+ fresh = _read_fresh_node(node.children[2])
+ return html_paths.element(tag_names, class_names=class_names, fresh=fresh)
+
+
+def _read_tag_names_node(node):
+ return [
+ child.text
+ for child in _repeated_children_with_separator(node, has_whitespace=False)
+ ]
+
+
+def _read_class_names_node(class_names_node):
+ return [
+ _read_class_name_node(node)
+ for node in class_names_node.children
+ ]
+
+
+def _read_class_name_node(node):
+ return node.children[1].text
+
+
+def _read_fresh_node(node):
+ return len(node.children) > 0
+
+
+def _repeated_children_with_separator(node, has_whitespace):
+ yield node.children[0]
+
+ if has_whitespace:
+ sequence_node_index = 2
+ else:
+ sequence_node_index = 1
+
+ sequence_node = node.children[sequence_node_index]
+ for child in sequence_node.children:
+ yield child.children[sequence_node_index]
+
+
+_grammar = Grammar(r"""
+
+path = element whitespace* (">" whitespace* element)*
+
+element = tag_names class_name* fresh?
+
+tag_names = identifier ("|" identifier)*
+
+class_name = "." identifier
+
+fresh = ":fresh"
+
+identifier = ~"[A-Z0-9]*"i
+
+whitespace = ~"\s"*
+
+""")
+