From ed66bfe54f283cbf27bed4d5b4bddf0c1bdf4808 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Wed, 16 Nov 2016 20:33:51 +0000 Subject: Read separators in HTML paths --- .../zwobble/mammoth/internal/styles/HtmlPath.java | 4 +-- .../mammoth/internal/styles/HtmlPathElement.java | 10 +++---- .../internal/styles/parsing/HtmlPathParser.java | 23 +++++++++++---- .../internal/styles/parsing/TokenIterator.java | 22 +++++++++++++- .../styles/parsing/HtmlPathElementBuilder.java | 34 ++++++++++++++++++++++ .../tests/styles/parsing/HtmlPathParsingTests.java | 8 +++++ 6 files changed, 87 insertions(+), 14 deletions(-) create mode 100644 src/test/java/org/zwobble/mammoth/tests/styles/parsing/HtmlPathElementBuilder.java diff --git a/src/main/java/org/zwobble/mammoth/internal/styles/HtmlPath.java b/src/main/java/org/zwobble/mammoth/internal/styles/HtmlPath.java index 0ce5c46..0a5c300 100644 --- a/src/main/java/org/zwobble/mammoth/internal/styles/HtmlPath.java +++ b/src/main/java/org/zwobble/mammoth/internal/styles/HtmlPath.java @@ -23,7 +23,7 @@ public interface HtmlPath { } static HtmlPath element(String tagName, Map attributes) { - return new HtmlPathElements(list(new HtmlPathElement(list(tagName), attributes, false))); + return new HtmlPathElements(list(new HtmlPathElement(list(tagName), attributes, false, ""))); } static HtmlPath collapsibleElement(String tagName) { @@ -39,7 +39,7 @@ public interface HtmlPath { } static HtmlPath collapsibleElement(List tagNames, Map attributes) { - return new HtmlPathElements(list(new HtmlPathElement(tagNames, attributes, true))); + return new HtmlPathElements(list(new HtmlPathElement(tagNames, attributes, true, ""))); } Supplier> wrap(Supplier> generateNodes); diff --git a/src/main/java/org/zwobble/mammoth/internal/styles/HtmlPathElement.java b/src/main/java/org/zwobble/mammoth/internal/styles/HtmlPathElement.java index 4c4ff98..1be14af 100644 --- a/src/main/java/org/zwobble/mammoth/internal/styles/HtmlPathElement.java +++ b/src/main/java/org/zwobble/mammoth/internal/styles/HtmlPathElement.java @@ -11,26 +11,24 @@ import static org.zwobble.mammoth.internal.util.Lists.list; import static org.zwobble.mammoth.internal.util.Maps.map; public class HtmlPathElement { - public static HtmlPathElement fresh(String tagName) { - return new HtmlPathElement(list(tagName), map(), false); - } - public static HtmlPathElement collapsible(String tagName) { return collapsible(tagName, map()); } public static HtmlPathElement collapsible(String tagName, Map attributes) { - return new HtmlPathElement(list(tagName), attributes, true); + return new HtmlPathElement(list(tagName), attributes, true, ""); } private final List tagNames; private final Map attributes; private final boolean isCollapsible; + private final String separator; - public HtmlPathElement(List tagNames, Map attributes, boolean isCollapsible) { + public HtmlPathElement(List tagNames, Map attributes, boolean isCollapsible, String separator) { this.tagNames = tagNames; this.attributes = attributes; this.isCollapsible = isCollapsible; + this.separator = separator; } public Supplier> wrap(Supplier> generateNodes) { diff --git a/src/main/java/org/zwobble/mammoth/internal/styles/parsing/HtmlPathParser.java b/src/main/java/org/zwobble/mammoth/internal/styles/parsing/HtmlPathParser.java index 0d5c70b..a509bbb 100644 --- a/src/main/java/org/zwobble/mammoth/internal/styles/parsing/HtmlPathParser.java +++ b/src/main/java/org/zwobble/mammoth/internal/styles/parsing/HtmlPathParser.java @@ -44,7 +44,8 @@ public class HtmlPathParser { ? map() : map("class", String.join(" ", classNames)); boolean isFresh = parseIsFresh(tokens); - return new HtmlPathElement(tagNames, attributes, !isFresh); + String separator = parseSeparator(tokens); + return new HtmlPathElement(tagNames, attributes, !isFresh, separator); } private static List parseTagNames(TokenIterator tokens) { @@ -66,12 +67,24 @@ public class HtmlPathParser { } private static boolean parseIsFresh(TokenIterator tokens) { - if (tokens.peekTokenType() == TokenType.COLON) { - tokens.skip(); + return tokens.tryParse(() -> { + tokens.skip(TokenType.COLON); tokens.skip(TokenType.IDENTIFIER, "fresh"); - return true; + }); + } + + private static String parseSeparator(TokenIterator tokens) { + boolean isSeparator = tokens.tryParse(() -> { + tokens.skip(TokenType.COLON); + tokens.skip(TokenType.IDENTIFIER, "separator"); + }); + if (isSeparator) { + tokens.skip(TokenType.OPEN_PAREN); + String value = TokenParser.parseString(tokens); + tokens.skip(TokenType.CLOSE_PAREN); + return value; } else { - return false; + return ""; } } } diff --git a/src/main/java/org/zwobble/mammoth/internal/styles/parsing/TokenIterator.java b/src/main/java/org/zwobble/mammoth/internal/styles/parsing/TokenIterator.java index 0bb3f46..f79974d 100644 --- a/src/main/java/org/zwobble/mammoth/internal/styles/parsing/TokenIterator.java +++ b/src/main/java/org/zwobble/mammoth/internal/styles/parsing/TokenIterator.java @@ -16,7 +16,11 @@ public class TokenIterator { } public T peekTokenType(int count) { - return tokens.get(index + count).getTokenType(); + return peekToken(count).getTokenType(); + } + + public Token peekToken(int count) { + return tokens.get(index + count); } public Token next(T type) { @@ -60,4 +64,20 @@ public class TokenIterator { private LineParseException unexpectedTokenType(T expected, Token actual) { return new LineParseException(actual, "expected token of type " + expected + " but was of type " + actual.getTokenType()); } + + public boolean tryParse(Action action) { + int originalIndex = index; + try { + action.run(); + return true; + } + catch (LineParseException exception) { + index = originalIndex; + return false; + } + } + + public interface Action { + void run(); + } } diff --git a/src/test/java/org/zwobble/mammoth/tests/styles/parsing/HtmlPathElementBuilder.java b/src/test/java/org/zwobble/mammoth/tests/styles/parsing/HtmlPathElementBuilder.java new file mode 100644 index 0000000..a12b7ed --- /dev/null +++ b/src/test/java/org/zwobble/mammoth/tests/styles/parsing/HtmlPathElementBuilder.java @@ -0,0 +1,34 @@ +package org.zwobble.mammoth.tests.styles.parsing; + +import org.zwobble.mammoth.internal.styles.HtmlPathElement; + +import static org.zwobble.mammoth.internal.util.Lists.list; +import static org.zwobble.mammoth.internal.util.Maps.map; + +public class HtmlPathElementBuilder { + public static HtmlPathElementBuilder tagName(String tagName) { + return new HtmlPathElementBuilder(tagName, false, ""); + } + + private final String tagName; + private final boolean isCollapsible; + private final String separator; + + public HtmlPathElementBuilder(String tagName, boolean isCollapsible, String separator) { + this.tagName = tagName; + this.isCollapsible = isCollapsible; + this.separator = separator; + } + + public HtmlPathElementBuilder collapsible(boolean isCollapsible) { + return new HtmlPathElementBuilder(tagName, isCollapsible, separator); + } + + public HtmlPathElementBuilder separator(String separator) { + return new HtmlPathElementBuilder(tagName, isCollapsible, separator); + } + + public HtmlPathElement build() { + return new HtmlPathElement(list(tagName), map(), isCollapsible, separator); + } +} diff --git a/src/test/java/org/zwobble/mammoth/tests/styles/parsing/HtmlPathParsingTests.java b/src/test/java/org/zwobble/mammoth/tests/styles/parsing/HtmlPathParsingTests.java index 7ad3c35..7d67287 100644 --- a/src/test/java/org/zwobble/mammoth/tests/styles/parsing/HtmlPathParsingTests.java +++ b/src/test/java/org/zwobble/mammoth/tests/styles/parsing/HtmlPathParsingTests.java @@ -66,6 +66,14 @@ public class HtmlPathParsingTests { deepEquals(HtmlPath.element("p"))); } + @Test + public void canReadSeparatorForElements() { + assertThat( + parseHtmlPath("p:separator('x')"), + deepEquals(HtmlPath.elements(HtmlPathElementBuilder.tagName("p").collapsible(true).separator("x").build())) + ); + } + @Test public void canReadIgnoreElement() { assertThat( -- cgit v1.2.3