From 3e2786a004eddf968a5fa7d5a92dff5b1b5f7734 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Wed, 24 Feb 2016 08:16:16 +0000 Subject: Create internal package --- .../mammoth/internal/DocumentConverter.java | 258 ++++++++++++++++ .../mammoth/internal/documents/Bookmark.java | 18 ++ .../mammoth/internal/documents/Document.java | 21 ++ .../internal/documents/DocumentElement.java | 5 + .../internal/documents/DocumentElementVisitor.java | 20 ++ .../mammoth/internal/documents/Documents.java | 4 + .../mammoth/internal/documents/HasChildren.java | 7 + .../mammoth/internal/documents/Hyperlink.java | 42 +++ .../zwobble/mammoth/internal/documents/Image.java | 37 +++ .../mammoth/internal/documents/LineBreak.java | 13 + .../zwobble/mammoth/internal/documents/Note.java | 27 ++ .../mammoth/internal/documents/NoteReference.java | 32 ++ .../mammoth/internal/documents/NoteType.java | 6 + .../zwobble/mammoth/internal/documents/Notes.java | 27 ++ .../mammoth/internal/documents/NumberingLevel.java | 27 ++ .../mammoth/internal/documents/Paragraph.java | 33 +++ .../zwobble/mammoth/internal/documents/Run.java | 65 ++++ .../zwobble/mammoth/internal/documents/Style.java | 26 ++ .../zwobble/mammoth/internal/documents/Tab.java | 13 + .../zwobble/mammoth/internal/documents/Table.java | 21 ++ .../mammoth/internal/documents/TableCell.java | 21 ++ .../mammoth/internal/documents/TableRow.java | 21 ++ .../zwobble/mammoth/internal/documents/Text.java | 18 ++ .../internal/documents/VerticalAlignment.java | 7 + .../mammoth/internal/docx/BodyXmlReader.java | 329 +++++++++++++++++++++ .../mammoth/internal/docx/ContentTypes.java | 45 +++ .../mammoth/internal/docx/ContentTypesXml.java | 38 +++ .../mammoth/internal/docx/DocumentReader.java | 115 +++++++ .../mammoth/internal/docx/DocumentXmlReader.java | 23 ++ .../zwobble/mammoth/internal/docx/DocxFile.java | 15 + .../zwobble/mammoth/internal/docx/FileReader.java | 8 + .../mammoth/internal/docx/InMemoryDocxFile.java | 46 +++ .../mammoth/internal/docx/NotesXmlReader.java | 55 ++++ .../zwobble/mammoth/internal/docx/Numbering.java | 23 ++ .../mammoth/internal/docx/NumberingXml.java | 56 ++++ .../zwobble/mammoth/internal/docx/OfficeXml.java | 58 ++++ .../zwobble/mammoth/internal/docx/ReadResult.java | 91 ++++++ .../mammoth/internal/docx/Relationship.java | 13 + .../mammoth/internal/docx/Relationships.java | 20 ++ .../mammoth/internal/docx/RelationshipsXml.java | 22 ++ .../org/zwobble/mammoth/internal/docx/Styles.java | 28 ++ .../zwobble/mammoth/internal/docx/StylesXml.java | 33 +++ .../mammoth/internal/docx/ZippedDocxFile.java | 30 ++ .../org/zwobble/mammoth/internal/html/Html.java | 179 +++++++++++ .../zwobble/mammoth/internal/html/HtmlElement.java | 48 +++ .../mammoth/internal/html/HtmlForceWrite.java | 18 ++ .../zwobble/mammoth/internal/html/HtmlNode.java | 21 ++ .../internal/html/HtmlSelfClosingElement.java | 31 ++ .../mammoth/internal/html/HtmlTextNode.java | 23 ++ .../zwobble/mammoth/internal/html/HtmlWriter.java | 62 ++++ .../internal/styles/DocumentElementMatcher.java | 5 + .../internal/styles/DocumentElementMatching.java | 26 ++ .../zwobble/mammoth/internal/styles/HtmlPath.java | 51 ++++ .../mammoth/internal/styles/HtmlPathElement.java | 38 +++ .../mammoth/internal/styles/ParagraphMatcher.java | 50 ++++ .../mammoth/internal/styles/RunMatcher.java | 30 ++ .../zwobble/mammoth/internal/styles/StyleMap.java | 57 ++++ .../mammoth/internal/styles/StyleMapBuilder.java | 41 +++ .../mammoth/internal/styles/StyleMapping.java | 19 ++ .../mammoth/internal/styles/parsing/ListVar.java | 34 +++ .../mammoth/internal/styles/parsing/Parsing.java | 21 ++ .../internal/styles/parsing/StyleMapParser.java | 34 +++ .../styles/parsing/StyleMappingParser.java | 178 +++++++++++ .../org/zwobble/mammoth/internal/util/Casts.java | 13 + .../mammoth/internal/util/InputStreamSupplier.java | 9 + .../mammoth/internal/util/MammothIterables.java | 11 + .../mammoth/internal/util/MammothLists.java | 50 ++++ .../zwobble/mammoth/internal/util/MammothMaps.java | 32 ++ .../mammoth/internal/util/MammothOptionals.java | 30 ++ .../mammoth/internal/util/MammothStrings.java | 11 + .../mammoth/internal/xml/NullXmlElement.java | 25 ++ .../zwobble/mammoth/internal/xml/XmlElement.java | 89 ++++++ .../mammoth/internal/xml/XmlElementLike.java | 9 + .../mammoth/internal/xml/XmlElementList.java | 28 ++ .../org/zwobble/mammoth/internal/xml/XmlNode.java | 6 + .../mammoth/internal/xml/XmlNodeVisitor.java | 6 + .../org/zwobble/mammoth/internal/xml/XmlNodes.java | 29 ++ .../zwobble/mammoth/internal/xml/XmlTextNode.java | 28 ++ .../mammoth/internal/xml/parsing/ElementName.java | 19 ++ .../mammoth/internal/xml/parsing/SimpleSax.java | 64 ++++ .../internal/xml/parsing/SimpleSaxHandler.java | 9 + .../internal/xml/parsing/XmlElementBuilder.java | 28 ++ .../mammoth/internal/xml/parsing/XmlParser.java | 81 +++++ 83 files changed, 3360 insertions(+) create mode 100644 src/main/java/org/zwobble/mammoth/internal/DocumentConverter.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/documents/Bookmark.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/documents/Document.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/documents/DocumentElement.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/documents/DocumentElementVisitor.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/documents/Documents.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/documents/HasChildren.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/documents/Hyperlink.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/documents/Image.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/documents/LineBreak.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/documents/Note.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/documents/NoteReference.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/documents/NoteType.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/documents/Notes.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/documents/NumberingLevel.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/documents/Paragraph.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/documents/Run.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/documents/Style.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/documents/Tab.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/documents/Table.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/documents/TableCell.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/documents/TableRow.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/documents/Text.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/documents/VerticalAlignment.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/docx/BodyXmlReader.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/docx/ContentTypes.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/docx/ContentTypesXml.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/docx/DocumentReader.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/docx/DocumentXmlReader.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/docx/DocxFile.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/docx/FileReader.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/docx/InMemoryDocxFile.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/docx/NotesXmlReader.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/docx/Numbering.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/docx/NumberingXml.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/docx/OfficeXml.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/docx/ReadResult.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/docx/Relationship.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/docx/Relationships.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/docx/RelationshipsXml.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/docx/Styles.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/docx/StylesXml.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/docx/ZippedDocxFile.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/html/Html.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/html/HtmlElement.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/html/HtmlForceWrite.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/html/HtmlNode.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/html/HtmlSelfClosingElement.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/html/HtmlTextNode.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/html/HtmlWriter.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/styles/DocumentElementMatcher.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/styles/DocumentElementMatching.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/styles/HtmlPath.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/styles/HtmlPathElement.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/styles/ParagraphMatcher.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/styles/RunMatcher.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/styles/StyleMap.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/styles/StyleMapBuilder.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/styles/StyleMapping.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/styles/parsing/ListVar.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/styles/parsing/Parsing.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/styles/parsing/StyleMapParser.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/styles/parsing/StyleMappingParser.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/util/Casts.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/util/InputStreamSupplier.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/util/MammothIterables.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/util/MammothLists.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/util/MammothMaps.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/util/MammothOptionals.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/util/MammothStrings.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/xml/NullXmlElement.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/xml/XmlElement.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/xml/XmlElementLike.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/xml/XmlElementList.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/xml/XmlNode.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/xml/XmlNodeVisitor.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/xml/XmlNodes.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/xml/XmlTextNode.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/xml/parsing/ElementName.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/xml/parsing/SimpleSax.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/xml/parsing/SimpleSaxHandler.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/xml/parsing/XmlElementBuilder.java create mode 100644 src/main/java/org/zwobble/mammoth/internal/xml/parsing/XmlParser.java (limited to 'src/main/java/org/zwobble/mammoth/internal') diff --git a/src/main/java/org/zwobble/mammoth/internal/DocumentConverter.java b/src/main/java/org/zwobble/mammoth/internal/DocumentConverter.java new file mode 100644 index 0000000..5aa3c08 --- /dev/null +++ b/src/main/java/org/zwobble/mammoth/internal/DocumentConverter.java @@ -0,0 +1,258 @@ +package org.zwobble.mammoth.internal; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterables; +import com.google.common.io.ByteStreams; +import org.zwobble.mammoth.internal.documents.*; +import org.zwobble.mammoth.internal.html.Html; +import org.zwobble.mammoth.internal.html.HtmlNode; +import org.zwobble.mammoth.results.Result; +import org.zwobble.mammoth.results.Warning; +import org.zwobble.mammoth.internal.styles.HtmlPath; +import org.zwobble.mammoth.internal.styles.StyleMap; +import org.zwobble.mammoth.internal.util.MammothLists; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Base64; +import java.util.List; +import java.util.Map; + +import static org.zwobble.mammoth.results.Warning.warning; +import static org.zwobble.mammoth.internal.util.MammothLists.*; +import static org.zwobble.mammoth.internal.util.MammothMaps.map; + +public class DocumentConverter { + public static Result> convertToHtml(String idPrefix, boolean preserveEmptyParagraphs, StyleMap styleMap, Document document) { + DocumentConverter documentConverter = new DocumentConverter(idPrefix, preserveEmptyParagraphs, styleMap); + return new Result<>( + documentConverter.convertToHtml(document), + documentConverter.warnings.build()); + } + + private static List findNotes(Document document, Iterable noteReferences) { + return ImmutableList.copyOf(Iterables.transform( + noteReferences, + // TODO: handle missing notes + reference -> document.getNotes().findNote(reference.getNoteType(), reference.getNoteId()).get())); + } + + public static Result> convertToHtml(String idPrefix, boolean preserveEmptyParagraphs, StyleMap styleMap, DocumentElement element) { + DocumentConverter documentConverter = new DocumentConverter(idPrefix, preserveEmptyParagraphs, styleMap); + return new Result<>( + documentConverter.convertToHtml(element), + documentConverter.warnings.build()); + } + + private final String idPrefix; + private final boolean preserveEmptyParagraphs; + private final StyleMap styleMap; + private final List noteReferences = new ArrayList<>(); + private final ImmutableList.Builder warnings = ImmutableList.builder(); + + private DocumentConverter(String idPrefix, boolean preserveEmptyParagraphs, StyleMap styleMap) { + this.idPrefix = idPrefix; + this.preserveEmptyParagraphs = preserveEmptyParagraphs; + this.styleMap = styleMap; + } + + private List convertToHtml(Document document) { + List mainBody = convertChildrenToHtml(document); + // TODO: can you have note references inside a note? + List notes = findNotes(document, noteReferences); + if (notes.isEmpty()) { + return mainBody; + } else { + HtmlNode noteNode = Html.element("ol", + ImmutableList.copyOf(Iterables.transform(notes, this::convertToHtml))); + + return ImmutableList.copyOf(Iterables.concat(mainBody, list(noteNode))); + } + } + + private HtmlNode convertToHtml(Note note) { + String id = generateNoteHtmlId(note.getNoteType(), note.getId()); + String referenceId = generateNoteRefHtmlId(note.getNoteType(), note.getId()); + ImmutableList.Builder children = ImmutableList.builder(); + children.addAll(convertToHtml(note.getBody())); + // TODO: we probably want this to collapse more eagerly than other collapsible elements + // -- for instance, any paragraph will probably do, regardless of attributes. (Possible other elements will do too.) + children.add(Html.collapsibleElement("p", list( + Html.text(" "), + Html.element("a", map("href", "#" + referenceId), list(Html.text("↑")))))); + return Html.element("li", map("id", id), children.build()); + } + + private List convertToHtml(List elements) { + return eagerFlatMap( + elements, + this::convertToHtml); + } + + private List convertChildrenToHtml(HasChildren element) { + return convertToHtml(element.getChildren()); + } + + private List convertToHtml(DocumentElement element) { + return element.accept(new DocumentElementVisitor>() { + @Override + public List visit(Paragraph paragraph) { + List content = convertChildrenToHtml(paragraph); + List children = preserveEmptyParagraphs ? cons(Html.FORCE_WRITE, content) : content; + HtmlPath mapping = styleMap.getParagraphHtmlPath(paragraph) + .orElseGet(() -> { + if (paragraph.getStyle().isPresent()) { + warnings.add(warning("Unrecognised paragraph style: " + paragraph.getStyle().get().describe())); + } + return HtmlPath.element("p"); + }); + return mapping.wrap(children); + } + + @Override + public List visit(Run run) { + List nodes = convertChildrenToHtml(run); + if (run.isStrikethrough()) { + nodes = styleMap.getStrikethrough().wrap(nodes); + } + if (run.isUnderline()) { + nodes = styleMap.getUnderline().wrap(nodes); + } + if (run.getVerticalAlignment() == VerticalAlignment.SUBSCRIPT) { + nodes = list(Html.collapsibleElement("sub", nodes)); + } + if (run.getVerticalAlignment() == VerticalAlignment.SUPERSCRIPT) { + nodes = list(Html.collapsibleElement("sup", nodes)); + } + if (run.isItalic()) { + nodes = list(Html.collapsibleElement("em", nodes)); + } + if (run.isBold()) { + nodes = list(Html.collapsibleElement("strong", nodes)); + } + HtmlPath mapping = styleMap.getRunHtmlPath(run) + .orElseGet(() -> { + if (run.getStyle().isPresent()) { + warnings.add(warning("Unrecognised run style: " + run.getStyle().get().describe())); + } + return HtmlPath.EMPTY; + }); + return mapping.wrap(nodes); + } + + @Override + public List visit(Text text) { + if (text.getValue().isEmpty()) { + return list(); + } else { + return list(Html.text(text.getValue())); + } + } + + @Override + public List visit(Tab tab) { + return list(Html.text("\t")); + } + + @Override + public List visit(LineBreak lineBreak) { + return list(Html.selfClosingElement("br")); + } + + @Override + public List visit(Table table) { + return list(Html.element("table", convertChildrenToHtml(table))); + } + + @Override + public List visit(TableRow tableRow) { + return list(Html.element("tr", convertChildrenToHtml(tableRow))); + } + + @Override + public List visit(TableCell tableCell) { + return list(Html.element("td", + MammothLists.cons(Html.FORCE_WRITE, convertChildrenToHtml(tableCell)))); + } + + @Override + public List visit(Hyperlink hyperlink) { + Map attributes = map("href", generateHref(hyperlink)); + return list(Html.collapsibleElement("a", attributes, convertChildrenToHtml(hyperlink))); + } + + private String generateHref(Hyperlink hyperlink) { + if (hyperlink.getHref().isPresent()) { + return hyperlink.getHref().get(); + } else if (hyperlink.getAnchor().isPresent()) { + return "#" + generateId(hyperlink.getAnchor().get()); + } else { + return ""; + } + } + + @Override + public List visit(Bookmark bookmark) { + return list(Html.element("a", map("id", generateId(bookmark.getName())), list(Html.FORCE_WRITE))); + } + + @Override + public List visit(NoteReference noteReference) { + noteReferences.add(noteReference); + String noteAnchor = generateNoteHtmlId(noteReference.getNoteType(), noteReference.getNoteId()); + String noteReferenceAnchor = generateNoteRefHtmlId(noteReference.getNoteType(), noteReference.getNoteId()); + return list(Html.element("sup", list( + Html.element("a", map("href", "#" + noteAnchor, "id", noteReferenceAnchor), list( + Html.text("[" + noteReferences.size() + "]")))))); + } + + @Override + public List visit(Image image) { + // TODO: custom image handlers + // TODO: handle empty content type + return image.getContentType() + .map(contentType -> { + try { + ImmutableMap.Builder attributes = ImmutableMap.builder(); + + String base64 = Base64.getEncoder().encodeToString(ByteStreams.toByteArray(image.open())); + String src = "data:" + contentType + ";base64," + base64; + attributes.put("src", src); + + image.getAltText().ifPresent(altText -> attributes.put("alt", altText)); + + return list(Html.selfClosingElement("img", attributes.build())); + } catch (IOException exception) { + warnings.add(warning(exception.getMessage())); + return MammothLists.list(); + } + }) + .orElse(list()); + } + }); + } + + private String generateNoteHtmlId(NoteType noteType, String noteId) { + return generateId(noteTypeToIdFragment(noteType) + "-" + noteId); + } + + private String generateNoteRefHtmlId(NoteType noteType, String noteId) { + return generateId(noteTypeToIdFragment(noteType) + "-ref-" + noteId); + } + + private String noteTypeToIdFragment(NoteType noteType) { + switch (noteType) { + case FOOTNOTE: + return "footnote"; + case ENDNOTE: + return "endnote"; + default: + throw new UnsupportedOperationException(); + } + } + + private String generateId(String bookmarkName) { + return idPrefix + bookmarkName; + } +} diff --git a/src/main/java/org/zwobble/mammoth/internal/documents/Bookmark.java b/src/main/java/org/zwobble/mammoth/internal/documents/Bookmark.java new file mode 100644 index 0000000..cca6317 --- /dev/null +++ b/src/main/java/org/zwobble/mammoth/internal/documents/Bookmark.java @@ -0,0 +1,18 @@ +package org.zwobble.mammoth.internal.documents; + +public class Bookmark implements DocumentElement { + private final String name; + + public Bookmark(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + @Override + public T accept(DocumentElementVisitor visitor) { + return visitor.visit(this); + } +} diff --git a/src/main/java/org/zwobble/mammoth/internal/documents/Document.java b/src/main/java/org/zwobble/mammoth/internal/documents/Document.java new file mode 100644 index 0000000..447d6ed --- /dev/null +++ b/src/main/java/org/zwobble/mammoth/internal/documents/Document.java @@ -0,0 +1,21 @@ +package org.zwobble.mammoth.internal.documents; + +import java.util.List; + +public class Document implements HasChildren { + private final List children; + private final Notes notes; + + public Document(List children, Notes notes) { + this.children = children; + this.notes = notes; + } + + public List getChildren() { + return children; + } + + public Notes getNotes() { + return notes; + } +} diff --git a/src/main/java/org/zwobble/mammoth/internal/documents/DocumentElement.java b/src/main/java/org/zwobble/mammoth/internal/documents/DocumentElement.java new file mode 100644 index 0000000..b3360ed --- /dev/null +++ b/src/main/java/org/zwobble/mammoth/internal/documents/DocumentElement.java @@ -0,0 +1,5 @@ +package org.zwobble.mammoth.internal.documents; + +public interface DocumentElement { + T accept(DocumentElementVisitor visitor); +} diff --git a/src/main/java/org/zwobble/mammoth/internal/documents/DocumentElementVisitor.java b/src/main/java/org/zwobble/mammoth/internal/documents/DocumentElementVisitor.java new file mode 100644 index 0000000..569a525 --- /dev/null +++ b/src/main/java/org/zwobble/mammoth/internal/documents/DocumentElementVisitor.java @@ -0,0 +1,20 @@ +package org.zwobble.mammoth.internal.documents; + +public interface DocumentElementVisitor { + T visit(Paragraph paragraph); + T visit(Run run); + T visit(Text text); + + T visit(Tab tab); + T visit(LineBreak lineBreak); + + T visit(Table table); + T visit(TableRow tableRow); + T visit(TableCell tableCell); + + T visit(Hyperlink hyperlink); + T visit(Bookmark bookmark); + T visit(NoteReference noteReference); + + T visit(Image image); +} diff --git a/src/main/java/org/zwobble/mammoth/internal/documents/Documents.java b/src/main/java/org/zwobble/mammoth/internal/documents/Documents.java new file mode 100644 index 0000000..64a5d1c --- /dev/null +++ b/src/main/java/org/zwobble/mammoth/internal/documents/Documents.java @@ -0,0 +1,4 @@ +package org.zwobble.mammoth.internal.documents; + +public class Documents { +} diff --git a/src/main/java/org/zwobble/mammoth/internal/documents/HasChildren.java b/src/main/java/org/zwobble/mammoth/internal/documents/HasChildren.java new file mode 100644 index 0000000..2a5280e --- /dev/null +++ b/src/main/java/org/zwobble/mammoth/internal/documents/HasChildren.java @@ -0,0 +1,7 @@ +package org.zwobble.mammoth.internal.documents; + +import java.util.List; + +public interface HasChildren { + List getChildren(); +} diff --git a/src/main/java/org/zwobble/mammoth/internal/documents/Hyperlink.java b/src/main/java/org/zwobble/mammoth/internal/documents/Hyperlink.java new file mode 100644 index 0000000..ceb558f --- /dev/null +++ b/src/main/java/org/zwobble/mammoth/internal/documents/Hyperlink.java @@ -0,0 +1,42 @@ +package org.zwobble.mammoth.internal.documents; + +import java.util.List; +import java.util.Optional; + +public class Hyperlink implements DocumentElement, HasChildren { + public static Hyperlink href(String href, List children) { + return new Hyperlink(Optional.of(href), Optional.empty(), children); + } + + public static Hyperlink anchor(String anchor, List children) { + return new Hyperlink(Optional.empty(), Optional.of(anchor), children); + } + + private final Optional href; + private final Optional anchor; + private final List children; + + private Hyperlink(Optional href, Optional anchor, List children) { + this.href = href; + this.anchor = anchor; + this.children = children; + } + + public Optional getHref() { + return href; + } + + public Optional getAnchor() { + return anchor; + } + + @Override + public List getChildren() { + return children; + } + + @Override + public T accept(DocumentElementVisitor visitor) { + return visitor.visit(this); + } +} diff --git a/src/main/java/org/zwobble/mammoth/internal/documents/Image.java b/src/main/java/org/zwobble/mammoth/internal/documents/Image.java new file mode 100644 index 0000000..8ceee7c --- /dev/null +++ b/src/main/java/org/zwobble/mammoth/internal/documents/Image.java @@ -0,0 +1,37 @@ +package org.zwobble.mammoth.internal.documents; + +import org.zwobble.mammoth.internal.util.InputStreamSupplier; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Optional; + +public class Image implements DocumentElement { + + private final Optional altText; + private final Optional contentType; + private final InputStreamSupplier open; + + public Image(Optional altText, Optional contentType, InputStreamSupplier open) { + this.altText = altText; + this.contentType = contentType; + this.open = open; + } + + public Optional getAltText() { + return altText; + } + + public Optional getContentType() { + return contentType; + } + + public InputStream open() throws IOException { + return open.open(); + } + + @Override + public T accept(DocumentElementVisitor visitor) { + return visitor.visit(this); + } +} diff --git a/src/main/java/org/zwobble/mammoth/internal/documents/LineBreak.java b/src/main/java/org/zwobble/mammoth/internal/documents/LineBreak.java new file mode 100644 index 0000000..00b2a06 --- /dev/null +++ b/src/main/java/org/zwobble/mammoth/internal/documents/LineBreak.java @@ -0,0 +1,13 @@ +package org.zwobble.mammoth.internal.documents; + +public class LineBreak implements DocumentElement { + public static final LineBreak LINE_BREAK = new LineBreak(); + + private LineBreak() { + } + + @Override + public T accept(DocumentElementVisitor visitor) { + return visitor.visit(this); + } +} diff --git a/src/main/java/org/zwobble/mammoth/internal/documents/Note.java b/src/main/java/org/zwobble/mammoth/internal/documents/Note.java new file mode 100644 index 0000000..d7d741b --- /dev/null +++ b/src/main/java/org/zwobble/mammoth/internal/documents/Note.java @@ -0,0 +1,27 @@ +package org.zwobble.mammoth.internal.documents; + +import java.util.List; + +public class Note { + private final NoteType noteType; + private final String id; + private final List body; + + public Note(NoteType noteType, String id, List body) { + this.noteType = noteType; + this.id = id; + this.body = body; + } + + public NoteType getNoteType() { + return noteType; + } + + public String getId() { + return id; + } + + public List getBody() { + return body; + } +} diff --git a/src/main/java/org/zwobble/mammoth/internal/documents/NoteReference.java b/src/main/java/org/zwobble/mammoth/internal/documents/NoteReference.java new file mode 100644 index 0000000..7d0beb2 --- /dev/null +++ b/src/main/java/org/zwobble/mammoth/internal/documents/NoteReference.java @@ -0,0 +1,32 @@ +package org.zwobble.mammoth.internal.documents; + +public class NoteReference implements DocumentElement { + public static NoteReference footnoteReference(String noteId) { + return new NoteReference(NoteType.FOOTNOTE, noteId); + } + + public static NoteReference endnoteReference(String noteId) { + return new NoteReference(NoteType.ENDNOTE, noteId); + } + + private final NoteType noteType; + private final String noteId; + + public NoteReference(NoteType noteType, String noteId) { + this.noteType = noteType; + this.noteId = noteId; + } + + public NoteType getNoteType() { + return noteType; + } + + public String getNoteId() { + return noteId; + } + + @Override + public T accept(DocumentElementVisitor visitor) { + return visitor.visit(this); + } +} diff --git a/src/main/java/org/zwobble/mammoth/internal/documents/NoteType.java b/src/main/java/org/zwobble/mammoth/internal/documents/NoteType.java new file mode 100644 index 0000000..47defc1 --- /dev/null +++ b/src/main/java/org/zwobble/mammoth/internal/documents/NoteType.java @@ -0,0 +1,6 @@ +package org.zwobble.mammoth.internal.documents; + +public enum NoteType { + FOOTNOTE, + ENDNOTE +} diff --git a/src/main/java/org/zwobble/mammoth/internal/documents/Notes.java b/src/main/java/org/zwobble/mammoth/internal/documents/Notes.java new file mode 100644 index 0000000..d8ca28d --- /dev/null +++ b/src/main/java/org/zwobble/mammoth/internal/documents/Notes.java @@ -0,0 +1,27 @@ +package org.zwobble.mammoth.internal.documents; + +import com.google.common.collect.Maps; +import com.google.common.collect.Multimaps; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import static org.zwobble.mammoth.internal.util.MammothLists.list; + +public class Notes { + public final static Notes EMPTY = new Notes(list()); + + private final Map> notes; + + public Notes(List notes) { + this.notes = Maps.transformValues( + Multimaps.index(notes, Note::getNoteType).asMap(), + notesOfType -> Maps.uniqueIndex(notesOfType, Note::getId)); + } + + public Optional findNote(NoteType noteType, String noteId) { + return Optional.ofNullable(notes.get(noteType)) + .flatMap(notesOfType -> Optional.ofNullable(notesOfType.get(noteId))); + } +} diff --git a/src/main/java/org/zwobble/mammoth/internal/documents/NumberingLevel.java b/src/main/java/org/zwobble/mammoth/internal/documents/NumberingLevel.java new file mode 100644 index 0000000..592d96f --- /dev/null +++ b/src/main/java/org/zwobble/mammoth/internal/documents/NumberingLevel.java @@ -0,0 +1,27 @@ +package org.zwobble.mammoth.internal.documents; + +public class NumberingLevel { + public static NumberingLevel ordered(String levelIndex) { + return new NumberingLevel(levelIndex, true); + } + + public static NumberingLevel unordered(String levelIndex) { + return new NumberingLevel(levelIndex, false); + } + + private final String levelIndex; + private final boolean isOrdered; + + public NumberingLevel(String levelIndex, boolean isOrdered) { + this.levelIndex = levelIndex; + this.isOrdered = isOrdered; + } + + public String getLevelIndex() { + return levelIndex; + } + + public boolean isOrdered() { + return isOrdered; + } +} diff --git a/src/main/java/org/zwobble/mammoth/internal/documents/Paragraph.java b/src/main/java/org/zwobble/mammoth/internal/documents/Paragraph.java new file mode 100644 index 0000000..66ea009 --- /dev/null +++ b/src/main/java/org/zwobble/mammoth/internal/documents/Paragraph.java @@ -0,0 +1,33 @@ +package org.zwobble.mammoth.internal.documents; + +import java.util.List; +import java.util.Optional; + +public class Paragraph implements DocumentElement, HasChildren { + private final Optional