diff options
| author | Michael Williamson <mike@zwobble.org> | 2016-02-13 17:45:31 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2016-02-13 17:46:12 +0000 |
| commit | 15127cb39b2014dd7b2218fafcba970045ddadef (patch) | |
| tree | 87f58962a4b00c145a2d318d0918d99577e448f0 | |
| parent | 2ccbdb0cb934ca4938221541ab5f53f08323a8dc (diff) | |
Read numbering from parapgraph properties
7 files changed, 66 insertions, 17 deletions
diff --git a/src/main/java/org/zwobble/mammoth/Mammoth.java b/src/main/java/org/zwobble/mammoth/Mammoth.java index e834b3b..05080cf 100644 --- a/src/main/java/org/zwobble/mammoth/Mammoth.java +++ b/src/main/java/org/zwobble/mammoth/Mammoth.java @@ -2,10 +2,7 @@ package org.zwobble.mammoth; import com.google.common.base.Joiner; import org.zwobble.mammoth.documents.*; -import org.zwobble.mammoth.docx.BodyXmlReader; -import org.zwobble.mammoth.docx.DocumentXmlReader; -import org.zwobble.mammoth.docx.OfficeXml; -import org.zwobble.mammoth.docx.Styles; +import org.zwobble.mammoth.docx.*; import org.zwobble.mammoth.xml.XmlElement; import java.io.File; @@ -22,7 +19,8 @@ public class Mammoth { XmlElement documentXml = OfficeXml.parseXml(zipFile.getInputStream(entry)); Styles styles = Styles.EMPTY; - Document document = new DocumentXmlReader(new BodyXmlReader(styles)).readElement(documentXml); + Numbering numbering = Numbering.EMPTY; + Document document = new DocumentXmlReader(new BodyXmlReader(styles, numbering)).readElement(documentXml); return convertToHtml(document); } catch (IOException e) { throw new UnsupportedOperationException("Should return a result of failure"); diff --git a/src/main/java/org/zwobble/mammoth/documents/NumberingLevel.java b/src/main/java/org/zwobble/mammoth/documents/NumberingLevel.java index ca134b9..cdbb0c4 100644 --- a/src/main/java/org/zwobble/mammoth/documents/NumberingLevel.java +++ b/src/main/java/org/zwobble/mammoth/documents/NumberingLevel.java @@ -1,6 +1,10 @@ package org.zwobble.mammoth.documents; public class NumberingLevel { + public static NumberingLevel ordered(String levelIndex) { + return new NumberingLevel(levelIndex, true); + } + private final String levelIndex; private final boolean isOrdered; diff --git a/src/main/java/org/zwobble/mammoth/docx/BodyXmlReader.java b/src/main/java/org/zwobble/mammoth/docx/BodyXmlReader.java index 73bab7e..42cee65 100644 --- a/src/main/java/org/zwobble/mammoth/docx/BodyXmlReader.java +++ b/src/main/java/org/zwobble/mammoth/docx/BodyXmlReader.java @@ -14,9 +14,11 @@ import static org.zwobble.mammoth.util.MammothLists.list; public class BodyXmlReader { private final Styles styles; + private final Numbering numbering; - public BodyXmlReader(Styles styles) { + public BodyXmlReader(Styles styles, Numbering numbering) { this.styles = styles; + this.numbering = numbering; } public List<DocumentElement> readElement(XmlElement element) { @@ -46,16 +48,28 @@ public class BodyXmlReader { } private Paragraph readParagraph(XmlElement element) { - return new Paragraph(readParagraphStyle(element), readNumbering(element), readElements(element.children())); + XmlElementLike properties = element.findChildOrEmpty("w:pPr"); + return new Paragraph( + readParagraphStyle(properties), + readNumbering(properties), + readElements(element.children())); } - private Optional<Style> readParagraphStyle(XmlElement paragraph) { - XmlElementLike properties = paragraph.findChildOrEmpty("w:pPr"); - return properties.findChildOrEmpty("w:pStyle").getAttributeOrNone("w:val") - .map(styleId -> styles.findParagraphStyleById(styleId).orElse(new Style(styleId, Optional.empty()))); + private Optional<Style> readParagraphStyle(XmlElementLike properties) { + return properties.findChildOrEmpty("w:pStyle") + .getAttributeOrNone("w:val") + .map(styleId -> styles.findParagraphStyleById(styleId) + .orElse(new Style(styleId, Optional.empty()))); } - private Optional<NumberingLevel> readNumbering(XmlElement element) { - return Optional.empty(); + private Optional<NumberingLevel> readNumbering(XmlElementLike properties) { + XmlElementLike numberingProperties = properties.findChildOrEmpty("w:numPr"); + Optional<String> numId = numberingProperties.findChildOrEmpty("w:numId").getAttributeOrNone("w:val"); + Optional<String> levelIndex = numberingProperties.findChildOrEmpty("w:ilvl").getAttributeOrNone("w:val"); + if (numId.isPresent() && levelIndex.isPresent()) { + return numbering.findLevel(numId.get(), levelIndex.get()); + } else { + return Optional.empty(); + } } } diff --git a/src/main/java/org/zwobble/mammoth/docx/Numbering.java b/src/main/java/org/zwobble/mammoth/docx/Numbering.java index 43b3e56..2f381dc 100644 --- a/src/main/java/org/zwobble/mammoth/docx/Numbering.java +++ b/src/main/java/org/zwobble/mammoth/docx/Numbering.java @@ -5,7 +5,11 @@ import org.zwobble.mammoth.documents.NumberingLevel; import java.util.Map; import java.util.Optional; +import static org.zwobble.mammoth.util.MammothMaps.map; + public class Numbering { + public static final Numbering EMPTY = new Numbering(map()); + private final Map<String, Map<String, NumberingLevel>> numbering; public Numbering(Map<String, Map<String, NumberingLevel>> numbering) { diff --git a/src/test/java/org/zwobble/mammoth/tests/DeepReflectionMatcher.java b/src/test/java/org/zwobble/mammoth/tests/DeepReflectionMatcher.java index 09258af..2d70d3e 100644 --- a/src/test/java/org/zwobble/mammoth/tests/DeepReflectionMatcher.java +++ b/src/test/java/org/zwobble/mammoth/tests/DeepReflectionMatcher.java @@ -53,7 +53,11 @@ public class DeepReflectionMatcher<T> extends TypeSafeDiagnosingMatcher<T> { } if (expected instanceof String) { - return matchesString(path, expected, actual, mismatchDescription); + return matchesPrimitive(path, expected, actual, mismatchDescription); + } + + if (expected instanceof Boolean) { + return matchesPrimitive(path, expected, actual, mismatchDescription); } for (Field field : fields(expected.getClass())) { @@ -139,7 +143,7 @@ public class DeepReflectionMatcher<T> extends TypeSafeDiagnosingMatcher<T> { return true; } - private static <T> boolean matchesString(String path, T expected, T actual, Description mismatchDescription) { + private static <T> boolean matchesPrimitive(String path, T expected, T actual, Description mismatchDescription) { Matcher<Object> matcher = Matchers.equalTo(expected); if (!matcher.matches(actual)) { appendPath(mismatchDescription, path); @@ -160,7 +164,7 @@ public class DeepReflectionMatcher<T> extends TypeSafeDiagnosingMatcher<T> { } private static String describeValue(Object value) { - if (value instanceof String) { + if (value instanceof String || value instanceof Boolean) { return value.toString(); } else if (value instanceof Optional) { Optional<?> optional = (Optional)value; diff --git a/src/test/java/org/zwobble/mammoth/tests/docx/BodyXmlReaderMakers.java b/src/test/java/org/zwobble/mammoth/tests/docx/BodyXmlReaderMakers.java index 6dafdee..9df21e9 100644 --- a/src/test/java/org/zwobble/mammoth/tests/docx/BodyXmlReaderMakers.java +++ b/src/test/java/org/zwobble/mammoth/tests/docx/BodyXmlReaderMakers.java @@ -3,13 +3,17 @@ package org.zwobble.mammoth.tests.docx; import com.natpryce.makeiteasy.Instantiator; import com.natpryce.makeiteasy.Property; import org.zwobble.mammoth.docx.BodyXmlReader; +import org.zwobble.mammoth.docx.Numbering; import org.zwobble.mammoth.docx.Styles; import static com.natpryce.makeiteasy.Property.newProperty; public class BodyXmlReaderMakers { public static final Property<BodyXmlReader, Styles> STYLES = newProperty(); + public static final Property<BodyXmlReader, Numbering> NUMBERING = newProperty(); public static final Instantiator<BodyXmlReader> bodyReader = - propertyLookup -> new BodyXmlReader(propertyLookup.valueOf(STYLES, Styles.EMPTY)); + propertyLookup -> new BodyXmlReader( + propertyLookup.valueOf(STYLES, Styles.EMPTY), + propertyLookup.valueOf(NUMBERING, Numbering.EMPTY)); } diff --git a/src/test/java/org/zwobble/mammoth/tests/docx/BodyXmlTests.java b/src/test/java/org/zwobble/mammoth/tests/docx/BodyXmlTests.java index d1dac9d..0a755e4 100644 --- a/src/test/java/org/zwobble/mammoth/tests/docx/BodyXmlTests.java +++ b/src/test/java/org/zwobble/mammoth/tests/docx/BodyXmlTests.java @@ -5,6 +5,7 @@ import org.hamcrest.Matcher; import org.junit.Test; import org.zwobble.mammoth.documents.*; import org.zwobble.mammoth.docx.BodyXmlReader; +import org.zwobble.mammoth.docx.Numbering; import org.zwobble.mammoth.docx.Styles; import org.zwobble.mammoth.tests.DeepReflectionMatcher; import org.zwobble.mammoth.xml.XmlElement; @@ -21,6 +22,7 @@ import static org.hamcrest.Matchers.hasProperty; import static org.zwobble.mammoth.tests.DeepReflectionMatcher.deepEquals; import static org.zwobble.mammoth.tests.documents.DocumentElementMakers.CHILDREN; import static org.zwobble.mammoth.tests.documents.DocumentElementMakers.PARAGRAPH; +import static org.zwobble.mammoth.tests.docx.BodyXmlReaderMakers.NUMBERING; import static org.zwobble.mammoth.tests.docx.BodyXmlReaderMakers.STYLES; import static org.zwobble.mammoth.tests.docx.BodyXmlReaderMakers.bodyReader; import static org.zwobble.mammoth.util.MammothLists.list; @@ -93,6 +95,21 @@ public class BodyXmlTests { hasNumbering(Optional.empty())); } + @Test + public void paragraphHasNumberingPropertiesFromParagraphPropertiesIfPresent() { + XmlElement element = paragraphXml(list( + element("w:pPr", list( + element("w:numPr", map(), list( + element("w:ilvl", map("w:val", "1")), + element("w:numId", map("w:val", "42")))))))); + + Numbering numbering = new Numbering(map("42", map("1", NumberingLevel.ordered("1")))); + + assertThat( + read(a(bodyReader, with(NUMBERING, numbering)), element), + hasNumbering(NumberingLevel.ordered("1"))); + } + private static DocumentElement read(Maker<BodyXmlReader> reader, XmlElement element) { return reader.make().readElement(element).get(0); } @@ -129,6 +146,10 @@ public class BodyXmlTests { return hasProperty("style", deepEquals(expected)); } + private Matcher<? super DocumentElement> hasNumbering(NumberingLevel expected) { + return hasNumbering(Optional.of(expected)); + } + private Matcher<? super DocumentElement> hasNumbering(Optional<NumberingLevel> expected) { return hasProperty("numbering", deepEquals(expected)); } |
