From 9a3a8523419efa46ed46c3044a5078e34928a7ed Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sun, 14 Feb 2016 18:37:42 +0000 Subject: Convert note references and notes to HTML Currently missing the back link --- .../org/zwobble/mammoth/DocumentConverter.java | 93 +++++++++++++++++++--- 1 file changed, 82 insertions(+), 11 deletions(-) (limited to 'src/main/java/org/zwobble/mammoth/DocumentConverter.java') diff --git a/src/main/java/org/zwobble/mammoth/DocumentConverter.java b/src/main/java/org/zwobble/mammoth/DocumentConverter.java index 1c42b0b..6f59cba 100644 --- a/src/main/java/org/zwobble/mammoth/DocumentConverter.java +++ b/src/main/java/org/zwobble/mammoth/DocumentConverter.java @@ -1,6 +1,8 @@ package org.zwobble.mammoth; +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.documents.*; import org.zwobble.mammoth.html.Html; @@ -16,23 +18,68 @@ import static org.zwobble.mammoth.util.MammothLists.list; import static org.zwobble.mammoth.util.MammothMaps.map; public class DocumentConverter { + public static List convertToHtml(String idPrefix, Document document) { + DocumentConverter documentConverter = new DocumentConverter(idPrefix); + List mainBody = documentConverter.convertChildrenToHtml(document); + // TODO: can you have note references inside a note? + List notes = findNotes(document); + if (notes.isEmpty()) { + return mainBody; + } else { + HtmlNode noteNode = Html.element("ol", + ImmutableList.copyOf(Iterables.transform(notes, documentConverter::convertToHtml))); + + return ImmutableList.copyOf(Iterables.concat(mainBody, list(noteNode))); + } + } + + private static List findNotes(Document document) { + Iterable noteReferences = Iterables.filter(descendants(document), NoteReference.class); + return ImmutableList.copyOf(Iterables.transform( + noteReferences, + // TODO: handle missing notes + reference -> document.getNotes().findNote(reference.getNoteType(), reference.getNoteId()).get())); + } + + private static Iterable descendants(HasChildren element) { + return Iterables.concat(Iterables.transform(element.getChildren(), DocumentConverter::descendantsAndSelf)); + } + + private static Iterable descendantsAndSelf(DocumentElement element) { + if (element instanceof HasChildren) { + HasChildren hasChildren = (HasChildren) element; + return Iterables.concat(descendants(hasChildren), list(element)); + } else { + return list(element); + } + } + + public static List convertToHtml(String idPrefix, DocumentElement element) { + return new DocumentConverter(idPrefix).convertToHtml(element); + } + private final String idPrefix; - public DocumentConverter(String idPrefix) { + private DocumentConverter(String idPrefix) { this.idPrefix = idPrefix; } - public List convertToHtml(Document document) { - return convertChildrenToHtml(document); + private HtmlNode convertToHtml(Note note) { + String id = generateNoteHtmlId(note.getNoteType(), note.getId()); + return Html.element("li", map("id", id), convertToHtml(note.getBody())); } - private List convertChildrenToHtml(HasChildren element) { + private List convertToHtml(List elements) { return eagerFlatMap( - element.getChildren(), + elements, this::convertToHtml); } - public List convertToHtml(DocumentElement element) { + 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) { @@ -120,13 +167,14 @@ public class DocumentConverter { return list(Html.element("a", map("id", generateId(bookmark.getName())))); } - private String generateId(String bookmarkName) { - return idPrefix + "-" + bookmarkName; - } - @Override public List visit(NoteReference noteReference) { - throw new UnsupportedOperationException(); + 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( + // TODO: increment note indices + Html.text("[1]")))))); } @Override @@ -154,4 +202,27 @@ public class DocumentConverter { } }); } + + 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; + } } -- cgit v1.2.3