From 244ed7482aedf44a8afccc7b2f7f77c977974f82 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Mon, 27 Mar 2017 19:20:19 +0100 Subject: Add custom image converters --- .../org/zwobble/mammoth/DocumentConverter.java | 9 +++++ .../java/org/zwobble/mammoth/images/Image.java | 11 ++++++ .../org/zwobble/mammoth/images/ImageConverter.java | 13 +++++++ .../internal/conversion/DocumentToHtml.java | 28 ++++++++++---- .../internal/conversion/DocumentToHtmlOptions.java | 44 ++++++++++++++++++---- 5 files changed, 89 insertions(+), 16 deletions(-) create mode 100644 src/main/java/org/zwobble/mammoth/images/Image.java create mode 100644 src/main/java/org/zwobble/mammoth/images/ImageConverter.java (limited to 'src/main/java/org/zwobble') 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; @@ -59,6 +60,14 @@ public class DocumentConverter { return new DocumentConverter(options.disableEmbeddedStyleMap()); } + /** + * By default, images are converted to {@code } 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)} 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 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 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 comments; private final List noteReferences = new ArrayList<>(); private final List 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 attributes = new HashMap<>(); - - String base64 = Base64Encoding.streamToBase64(image::open); - String src = "data:" + contentType + ";base64," + base64; - attributes.put("src", src); - + Map attributes = new HashMap<>(imageConverter.convert(new org.zwobble.mammoth.images.Image() { + @Override + public Optional 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; + } } -- cgit v1.2.3