aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/zwobble/mammoth/styles/parsing/HtmlPathParser.java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2016-02-23 19:49:30 +0000
committerMichael Williamson <mike@zwobble.org>2016-02-23 19:49:30 +0000
commit14a07f679a1ad1726445f363fee484e3b2d52884 (patch)
tree189d161601312119c027e00230cb82e09078b7e5 /src/main/java/org/zwobble/mammoth/styles/parsing/HtmlPathParser.java
parentc72cec263e12d18cd6fe35c1b224f5b68c587f11 (diff)
Move HTML path parsing rules into their own class
Diffstat (limited to 'src/main/java/org/zwobble/mammoth/styles/parsing/HtmlPathParser.java')
-rw-r--r--src/main/java/org/zwobble/mammoth/styles/parsing/HtmlPathParser.java68
1 files changed, 68 insertions, 0 deletions
diff --git a/src/main/java/org/zwobble/mammoth/styles/parsing/HtmlPathParser.java b/src/main/java/org/zwobble/mammoth/styles/parsing/HtmlPathParser.java
new file mode 100644
index 0000000..18e1107
--- /dev/null
+++ b/src/main/java/org/zwobble/mammoth/styles/parsing/HtmlPathParser.java
@@ -0,0 +1,68 @@
+package org.zwobble.mammoth.styles.parsing;
+
+import org.parboiled.BaseParser;
+import org.parboiled.Rule;
+import org.parboiled.support.Var;
+import org.zwobble.mammoth.styles.HtmlPath;
+import org.zwobble.mammoth.styles.HtmlPathElement;
+
+import static org.zwobble.mammoth.util.MammothMaps.map;
+
+public class HtmlPathParser extends BaseParser<HtmlPath> {
+ public Rule HtmlPath() {
+ ListVar<HtmlPathElement> elements = new ListVar<>();
+ return Sequence(Optional(HtmlPathElements(elements)), EOI, push(new HtmlPath(elements.build())));
+ }
+
+ Rule HtmlPathElements(ListVar<HtmlPathElement> elements) {
+ Var<HtmlPathElement> element = new Var<>();
+ return Sequence(
+ HtmlPathElement(element),
+ elements.append(element),
+ ZeroOrMore(Sequence(Whitespace(), Ch('>'), Whitespace(), HtmlPathElement(element), elements.append(element))));
+ }
+
+ Rule HtmlPathElement(Var<HtmlPathElement> element) {
+ ListVar<String> tagNames = new ListVar<>();
+ ListVar<String> classNames = new ListVar<>();
+ Var<Boolean> fresh = new Var<>();
+ return Sequence(
+ TagNames(tagNames),
+ ClassNames(classNames),
+ Fresh(fresh),
+ element.set(new HtmlPathElement(
+ tagNames.build(),
+ classNames.isEmpty() ? map() : map("class", String.join(" ", classNames.build())),
+ !fresh.get())));
+ }
+
+ Rule TagNames(ListVar<String> tagNames) {
+ return Sequence(
+ Identifier(),
+ tagNames.append(match()),
+ ZeroOrMore(Sequence("|", Identifier(), tagNames.append(match()))));
+ }
+
+ Rule ClassNames(ListVar<String> classNames) {
+ Var<String> className = new Var<>();
+ return ZeroOrMore(Sequence(ClassName(className), classNames.append(className)));
+ }
+
+ Rule ClassName(Var<String> className) {
+ return Sequence(".", Identifier(), className.set(match()));
+ }
+
+ Rule Fresh(Var<Boolean> fresh) {
+ return Sequence(fresh.set(false), Optional(":fresh", fresh.set(true)));
+ }
+
+ Rule Identifier() {
+ return Sequence(
+ FirstOf(CharRange('a', 'z'), CharRange('A', 'Z')),
+ ZeroOrMore(FirstOf(CharRange('a', 'z'), CharRange('A', 'Z'), CharRange('0', '9'), Ch('-'), Ch('_'))));
+ }
+
+ Rule Whitespace() {
+ return ZeroOrMore(AnyOf(" \t"));
+ }
+}