aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/zwobble/mammoth/DocumentConverter.java9
-rw-r--r--src/main/java/org/zwobble/mammoth/images/Image.java11
-rw-r--r--src/main/java/org/zwobble/mammoth/images/ImageConverter.java13
-rw-r--r--src/main/java/org/zwobble/mammoth/internal/conversion/DocumentToHtml.java28
-rw-r--r--src/main/java/org/zwobble/mammoth/internal/conversion/DocumentToHtmlOptions.java44
-rw-r--r--src/test/java/org/zwobble/mammoth/tests/MammothTests.java23
6 files changed, 110 insertions, 18 deletions
diff --git a/src/main/java/org/zwobble/mammoth/DocumentConverter.java b/src/main/java/org/zwobble/mammoth/DocumentConverter.java
index feba5ac..2dea8e8 100644
--- a/src/main/java/org/zwobble/mammoth/DocumentConverter.java
+++ b/src/main/java/org/zwobble/mammoth/DocumentConverter.java
@@ -1,5 +1,6 @@
package org.zwobble.mammoth;
+import org.zwobble.mammoth.images.ImageConverter;
import org.zwobble.mammoth.internal.InternalDocumentConverter;
import org.zwobble.mammoth.internal.conversion.DocumentToHtmlOptions;
@@ -60,6 +61,14 @@ public class DocumentConverter {
}
/**
+ * By default, images are converted to {@code <img>} elements with the source included inline in the {@code src} attribute.
+ * Call this to change how images are converted.
+ */
+ public DocumentConverter imageConverter(ImageConverter.ImgElement imageConverter) {
+ return new DocumentConverter(options.imageConverter(imageConverter));
+ }
+
+ /**
* Converts {@code stream} into an HTML string.
* Note that using this method instead of {@link #convertToHtml(File file)}
* means that relative paths to other files, such as images, cannot be resolved.
diff --git a/src/main/java/org/zwobble/mammoth/images/Image.java b/src/main/java/org/zwobble/mammoth/images/Image.java
new file mode 100644
index 0000000..977e27d
--- /dev/null
+++ b/src/main/java/org/zwobble/mammoth/images/Image.java
@@ -0,0 +1,11 @@
+package org.zwobble.mammoth.images;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Optional;
+
+public interface Image {
+ Optional<String> getAltText();
+ String getContentType();
+ InputStream getInputStream() throws IOException;
+}
diff --git a/src/main/java/org/zwobble/mammoth/images/ImageConverter.java b/src/main/java/org/zwobble/mammoth/images/ImageConverter.java
new file mode 100644
index 0000000..83480f2
--- /dev/null
+++ b/src/main/java/org/zwobble/mammoth/images/ImageConverter.java
@@ -0,0 +1,13 @@
+package org.zwobble.mammoth.images;
+
+import java.io.IOException;
+import java.util.Map;
+
+public class ImageConverter {
+ private ImageConverter() {
+ }
+
+ public interface ImgElement {
+ Map<String, String> convert(Image image) throws IOException;
+ }
+}
diff --git a/src/main/java/org/zwobble/mammoth/internal/conversion/DocumentToHtml.java b/src/main/java/org/zwobble/mammoth/internal/conversion/DocumentToHtml.java
index cfa4f56..bdb3d01 100644
--- a/src/main/java/org/zwobble/mammoth/internal/conversion/DocumentToHtml.java
+++ b/src/main/java/org/zwobble/mammoth/internal/conversion/DocumentToHtml.java
@@ -1,16 +1,17 @@
package org.zwobble.mammoth.internal.conversion;
+import org.zwobble.mammoth.images.ImageConverter;
import org.zwobble.mammoth.internal.documents.*;
import org.zwobble.mammoth.internal.html.Html;
import org.zwobble.mammoth.internal.html.HtmlNode;
import org.zwobble.mammoth.internal.results.InternalResult;
import org.zwobble.mammoth.internal.styles.HtmlPath;
import org.zwobble.mammoth.internal.styles.StyleMap;
-import org.zwobble.mammoth.internal.util.Base64Encoding;
import org.zwobble.mammoth.internal.util.Lists;
import org.zwobble.mammoth.internal.util.Maps;
import java.io.IOException;
+import java.io.InputStream;
import java.util.*;
import java.util.function.Supplier;
@@ -53,6 +54,7 @@ public class DocumentToHtml {
private final String idPrefix;
private final boolean preserveEmptyParagraphs;
private final StyleMap styleMap;
+ private final ImageConverter.ImgElement imageConverter;
private final Map<String, Comment> comments;
private final List<NoteReference> noteReferences = new ArrayList<>();
private final List<ReferencedComment> referencedComments = new ArrayList<>();
@@ -62,6 +64,7 @@ public class DocumentToHtml {
this.idPrefix = options.idPrefix();
this.preserveEmptyParagraphs = options.shouldPreserveEmptyParagraphs();
this.styleMap = options.styleMap();
+ this.imageConverter = options.imageConverter();
this.comments = Maps.toMapWithKey(comments, Comment::getCommentId);
}
@@ -278,14 +281,23 @@ public class DocumentToHtml {
return image.getContentType()
.map(contentType -> {
try {
- Map<String, String> attributes = new HashMap<>();
-
- String base64 = Base64Encoding.streamToBase64(image::open);
- String src = "data:" + contentType + ";base64," + base64;
- attributes.put("src", src);
-
+ Map<String, String> attributes = new HashMap<>(imageConverter.convert(new org.zwobble.mammoth.images.Image() {
+ @Override
+ public Optional<String> getAltText() {
+ return image.getAltText();
+ }
+
+ @Override
+ public String getContentType() {
+ return contentType;
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return image.open();
+ }
+ }));
image.getAltText().ifPresent(altText -> attributes.put("alt", altText));
-
return list(Html.element("img", attributes));
} catch (IOException exception) {
warnings.add(exception.getMessage());
diff --git a/src/main/java/org/zwobble/mammoth/internal/conversion/DocumentToHtmlOptions.java b/src/main/java/org/zwobble/mammoth/internal/conversion/DocumentToHtmlOptions.java
index 8a709af..52b2558 100644
--- a/src/main/java/org/zwobble/mammoth/internal/conversion/DocumentToHtmlOptions.java
+++ b/src/main/java/org/zwobble/mammoth/internal/conversion/DocumentToHtmlOptions.java
@@ -1,11 +1,28 @@
package org.zwobble.mammoth.internal.conversion;
+import org.zwobble.mammoth.images.ImageConverter;
import org.zwobble.mammoth.internal.styles.DefaultStyles;
import org.zwobble.mammoth.internal.styles.StyleMap;
import org.zwobble.mammoth.internal.styles.parsing.StyleMapParser;
+import org.zwobble.mammoth.internal.util.Base64Encoding;
+
+import static org.zwobble.mammoth.internal.util.Maps.map;
public class DocumentToHtmlOptions {
- public static final DocumentToHtmlOptions DEFAULT = new DocumentToHtmlOptions("", false, StyleMap.EMPTY, StyleMap.EMPTY, false, false);
+ public static final DocumentToHtmlOptions DEFAULT = new DocumentToHtmlOptions(
+ "",
+ false,
+ StyleMap.EMPTY,
+ StyleMap.EMPTY,
+ false,
+ false,
+ image -> {
+ String base64 = Base64Encoding.streamToBase64(image::getInputStream);
+ String src = "data:" + image.getContentType() + ";base64," + base64;
+ return map("src", src);
+ }
+
+ );
private final String idPrefix;
private final boolean preserveEmptyParagraphs;
@@ -13,6 +30,7 @@ public class DocumentToHtmlOptions {
private final StyleMap embeddedStyleMap;
private final boolean disableDefaultStyleMap;
private final boolean disableEmbeddedStyleMap;
+ private final ImageConverter.ImgElement imageConverter;
public DocumentToHtmlOptions(
String idPrefix,
@@ -20,7 +38,8 @@ public class DocumentToHtmlOptions {
StyleMap styleMap,
StyleMap embeddedStyleMap,
boolean disableDefaultStyleMap,
- boolean disableEmbeddedStyleMap
+ boolean disableEmbeddedStyleMap,
+ ImageConverter.ImgElement imageConverter
) {
this.idPrefix = idPrefix;
this.preserveEmptyParagraphs = preserveEmptyParagraphs;
@@ -28,14 +47,15 @@ public class DocumentToHtmlOptions {
this.embeddedStyleMap = embeddedStyleMap;
this.disableDefaultStyleMap = disableDefaultStyleMap;
this.disableEmbeddedStyleMap = disableEmbeddedStyleMap;
+ this.imageConverter = imageConverter;
}
public DocumentToHtmlOptions idPrefix(String prefix) {
- return new DocumentToHtmlOptions(prefix, preserveEmptyParagraphs, styleMap, embeddedStyleMap, disableDefaultStyleMap, disableEmbeddedStyleMap);
+ return new DocumentToHtmlOptions(prefix, preserveEmptyParagraphs, styleMap, embeddedStyleMap, disableDefaultStyleMap, disableEmbeddedStyleMap, imageConverter);
}
public DocumentToHtmlOptions preserveEmptyParagraphs() {
- return new DocumentToHtmlOptions(idPrefix, true, styleMap, embeddedStyleMap, disableDefaultStyleMap, disableEmbeddedStyleMap);
+ return new DocumentToHtmlOptions(idPrefix, true, styleMap, embeddedStyleMap, disableDefaultStyleMap, disableEmbeddedStyleMap, imageConverter);
}
public DocumentToHtmlOptions addStyleMap(String styleMap) {
@@ -43,19 +63,23 @@ public class DocumentToHtmlOptions {
}
public DocumentToHtmlOptions addStyleMap(StyleMap styleMap) {
- return new DocumentToHtmlOptions(idPrefix, preserveEmptyParagraphs, this.styleMap.update(styleMap), embeddedStyleMap, disableDefaultStyleMap, disableEmbeddedStyleMap);
+ return new DocumentToHtmlOptions(idPrefix, preserveEmptyParagraphs, this.styleMap.update(styleMap), embeddedStyleMap, disableDefaultStyleMap, disableEmbeddedStyleMap, imageConverter);
}
public DocumentToHtmlOptions disableDefaultStyleMap() {
- return new DocumentToHtmlOptions(idPrefix, preserveEmptyParagraphs, styleMap, embeddedStyleMap, true, disableEmbeddedStyleMap);
+ return new DocumentToHtmlOptions(idPrefix, preserveEmptyParagraphs, styleMap, embeddedStyleMap, true, disableEmbeddedStyleMap, imageConverter);
}
public DocumentToHtmlOptions disableEmbeddedStyleMap() {
- return new DocumentToHtmlOptions(idPrefix, preserveEmptyParagraphs, styleMap, embeddedStyleMap, disableDefaultStyleMap, true);
+ return new DocumentToHtmlOptions(idPrefix, preserveEmptyParagraphs, styleMap, embeddedStyleMap, disableDefaultStyleMap, true, imageConverter);
}
public DocumentToHtmlOptions addEmbeddedStyleMap(StyleMap embeddedStyleMap) {
- return new DocumentToHtmlOptions(idPrefix, preserveEmptyParagraphs, styleMap, embeddedStyleMap, disableDefaultStyleMap, disableEmbeddedStyleMap);
+ return new DocumentToHtmlOptions(idPrefix, preserveEmptyParagraphs, styleMap, embeddedStyleMap, disableDefaultStyleMap, disableEmbeddedStyleMap, imageConverter);
+ }
+
+ public DocumentToHtmlOptions imageConverter(ImageConverter.ImgElement imageConverter) {
+ return new DocumentToHtmlOptions(idPrefix, preserveEmptyParagraphs, styleMap, embeddedStyleMap, disableDefaultStyleMap, disableEmbeddedStyleMap, imageConverter);
}
public String idPrefix() {
@@ -77,4 +101,8 @@ public class DocumentToHtmlOptions {
styleMap = styleMap.update(this.styleMap);
return styleMap;
}
+
+ public ImageConverter.ImgElement imageConverter() {
+ return imageConverter;
+ }
}
diff --git a/src/test/java/org/zwobble/mammoth/tests/MammothTests.java b/src/test/java/org/zwobble/mammoth/tests/MammothTests.java
index ac81c76..393f1a7 100644
--- a/src/test/java/org/zwobble/mammoth/tests/MammothTests.java
+++ b/src/test/java/org/zwobble/mammoth/tests/MammothTests.java
@@ -3,11 +3,16 @@ package org.zwobble.mammoth.tests;
import org.junit.Test;
import org.zwobble.mammoth.DocumentConverter;
import org.zwobble.mammoth.Result;
-import org.zwobble.mammoth.internal.docx.EmbeddedStyleMap;
+import org.zwobble.mammoth.images.ImageConverter;
import org.zwobble.mammoth.internal.archives.InMemoryArchive;
+import org.zwobble.mammoth.internal.docx.EmbeddedStyleMap;
import org.zwobble.mammoth.internal.styles.parsing.ParseException;
+import org.zwobble.mammoth.internal.util.Base64Encoding;
-import java.io.*;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.function.Function;
@@ -15,6 +20,7 @@ import java.util.function.Function;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertThat;
import static org.zwobble.mammoth.internal.util.Lists.list;
+import static org.zwobble.mammoth.internal.util.Maps.map;
import static org.zwobble.mammoth.tests.ResultMatchers.isResult;
import static org.zwobble.mammoth.tests.ResultMatchers.isSuccess;
import static org.zwobble.mammoth.tests.util.MammothAsserts.assertThrows;
@@ -132,6 +138,19 @@ public class MammothTests {
}
@Test
+ public void imageConversionCanBeCustomised() throws IOException {
+ ImageConverter.ImgElement imageConverter = image -> {
+ String base64 = Base64Encoding.streamToBase64(image::getInputStream);
+ String src = base64.substring(0, 2) + "," + image.getContentType();
+ return map("src", src);
+ };
+ assertThat(
+ convertToHtml("tiny-picture.docx", converter -> converter.imageConverter(imageConverter)),
+ isSuccess("<p><img src=\"iV,image/png\" /></p>")
+ );
+ }
+
+ @Test
public void contentTypesAreRead() throws IOException {
assertThat(
convertToHtml("tiny-picture-custom-content-type.docx"),