From 478405aaa3bb86bb85e8d77ba41ac6b4612cb3df Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Fri, 2 Sep 2016 23:49:04 +0100 Subject: Use alt text title if description is blank or missing --- .../mammoth/internal/docx/BodyXmlReader.java | 6 +- .../zwobble/mammoth/tests/docx/BodyXmlTests.java | 74 ++++++++++++++++++---- 2 files changed, 68 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/main/java/org/zwobble/mammoth/internal/docx/BodyXmlReader.java b/src/main/java/org/zwobble/mammoth/internal/docx/BodyXmlReader.java index 0c514fb..5f93c4a 100644 --- a/src/main/java/org/zwobble/mammoth/internal/docx/BodyXmlReader.java +++ b/src/main/java/org/zwobble/mammoth/internal/docx/BodyXmlReader.java @@ -388,7 +388,11 @@ public class BodyXmlReader { } private ReadResult readInline(XmlElement element) { - Optional altText = element.findChildOrEmpty("wp:docPr").getAttributeOrNone("descr"); + XmlElementLike properties = element.findChildOrEmpty("wp:docPr"); + Optional altText = Optionals.first( + properties.getAttributeOrNone("descr").filter(description -> !description.trim().isEmpty()), + properties.getAttributeOrNone("title") + ); XmlElementList blips = element.findChildren("a:graphic") .findChildren("a:graphicData") .findChildren("pic:pic") 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 1cf1c3f..0b1857e 100644 --- a/src/test/java/org/zwobble/mammoth/tests/docx/BodyXmlTests.java +++ b/src/test/java/org/zwobble/mammoth/tests/docx/BodyXmlTests.java @@ -14,6 +14,7 @@ import org.zwobble.mammoth.tests.DeepReflectionMatcher; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; @@ -564,6 +565,45 @@ public class BodyXmlTests { inlineImageXml(embeddedBlipXml(image.relationshipId), image.altText)); } + @Test + public void altTextTitleIsUsedIfAltTextDescriptionIsBlank() throws IOException { + XmlElement element = inlineImageXml( + embeddedBlipXml(IMAGE_RELATIONSHIP_ID), + Optional.of(" "), + Optional.of("It's a hat") + ); + + Image image = readEmbeddedImage(element); + + assertThat(image, hasProperty("altText", deepEquals(Optional.of("It's a hat")))); + } + + @Test + public void altTextTitleIsUsedIfAltTextDescriptionIsMissing() throws IOException { + XmlElement element = inlineImageXml( + embeddedBlipXml(IMAGE_RELATIONSHIP_ID), + Optional.empty(), + Optional.of("It's a hat") + ); + + Image image = readEmbeddedImage(element); + + assertThat(image, hasProperty("altText", deepEquals(Optional.of("It's a hat")))); + } + + @Test + public void altTextDescriptionIsPreferredToAltTextTitle() throws IOException { + XmlElement element = inlineImageXml( + embeddedBlipXml(IMAGE_RELATIONSHIP_ID), + Optional.of("It's a hat"), + Optional.of("hat") + ); + + Image image = readEmbeddedImage(element); + + assertThat(image, hasProperty("altText", deepEquals(Optional.of("It's a hat")))); + } + @Test public void canReadAnchoredPictures() throws IOException { assertCanReadEmbeddedImage(image -> @@ -572,13 +612,7 @@ public class BodyXmlTests { private void assertCanReadEmbeddedImage(Function generateXml) throws IOException { XmlElement element = generateXml.apply(new EmbeddedImage(IMAGE_RELATIONSHIP_ID, "It's a hat")); - Relationships relationships = new Relationships(map( - IMAGE_RELATIONSHIP_ID, new Relationship("media/hat.png"))); - DocxFile file = InMemoryDocxFile.fromStrings(map("word/media/hat.png", IMAGE_BYTES)); - - Image image = (Image) readSuccess( - bodyReader(relationships, file), - element); + Image image = readEmbeddedImage(element); assertThat(image, allOf( hasProperty("altText", deepEquals(Optional.of("It's a hat"))), hasProperty("contentType", deepEquals(Optional.of("image/png"))))); @@ -587,6 +621,16 @@ public class BodyXmlTests { equalTo(IMAGE_BYTES)); } + private Image readEmbeddedImage(XmlElement element) { + Relationships relationships = new Relationships(map( + IMAGE_RELATIONSHIP_ID, new Relationship("media/hat.png"))); + DocxFile file = InMemoryDocxFile.fromStrings(map("word/media/hat.png", IMAGE_BYTES)); + + return (Image) readSuccess( + BodyXmlReaderMakers.bodyReader(relationships, file), + element); + } + private static String toString(InputStream stream) throws IOException { return new String(toByteArray(stream), StandardCharsets.UTF_8); } @@ -634,18 +678,26 @@ public class BodyXmlTests { } private XmlElement inlineImageXml(XmlElement blip, String description) { + return inlineImageXml(blip, Optional.of(description), Optional.empty()); + } + + private XmlElement inlineImageXml(XmlElement blip, Optional description, Optional title) { return element("w:drawing", list( - element("wp:inline", imageXml(blip, description)))); + element("wp:inline", imageXml(blip, description, title)))); } private XmlElement anchoredImageXml(XmlElement blip, String description) { return element("w:drawing", list( - element("wp:anchor", imageXml(blip, description)))); + element("wp:anchor", imageXml(blip, Optional.of(description), Optional.empty())))); } - private List imageXml(XmlElement blip, String description) { + private List imageXml(XmlElement blip, Optional description, Optional title) { + Map properties = new HashMap<>(); + description.ifPresent(value -> properties.put("descr", value)); + title.ifPresent(value -> properties.put("title", value)); + return list( - element("wp:docPr", map("descr", description)), + element("wp:docPr", properties), element("a:graphic", list( element("a:graphicData", list( element("pic:pic", list( -- cgit v1.2.3