diff options
| author | Michael Williamson <mike@zwobble.org> | 2016-02-14 18:37:42 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2016-02-14 18:37:42 +0000 |
| commit | 9a3a8523419efa46ed46c3044a5078e34928a7ed (patch) | |
| tree | 99ad6531ce633c2ee6b9dd88ee0841a6a122659f /src/main/java | |
| parent | a07cddd98e2fdad40d2226818b04be1787abc6cf (diff) | |
Convert note references and notes to HTML
Currently missing the back link
Diffstat (limited to 'src/main/java')
4 files changed, 95 insertions, 12 deletions
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<HtmlNode> convertToHtml(String idPrefix, Document document) { + DocumentConverter documentConverter = new DocumentConverter(idPrefix); + List<HtmlNode> mainBody = documentConverter.convertChildrenToHtml(document); + // TODO: can you have note references inside a note? + List<Note> 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<Note> findNotes(Document document) { + Iterable<NoteReference> 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<DocumentElement> descendants(HasChildren element) { + return Iterables.concat(Iterables.transform(element.getChildren(), DocumentConverter::descendantsAndSelf)); + } + + private static Iterable<DocumentElement> 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<HtmlNode> 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<HtmlNode> 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<HtmlNode> convertChildrenToHtml(HasChildren element) { + private List<HtmlNode> convertToHtml(List<DocumentElement> elements) { return eagerFlatMap( - element.getChildren(), + elements, this::convertToHtml); } - public List<HtmlNode> convertToHtml(DocumentElement element) { + private List<HtmlNode> convertChildrenToHtml(HasChildren element) { + return convertToHtml(element.getChildren()); + } + + private List<HtmlNode> convertToHtml(DocumentElement element) { return element.accept(new DocumentElementVisitor<List<HtmlNode>>() { @Override public List<HtmlNode> 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<HtmlNode> 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; + } } diff --git a/src/main/java/org/zwobble/mammoth/Mammoth.java b/src/main/java/org/zwobble/mammoth/Mammoth.java index 2201bd2..79e15f7 100644 --- a/src/main/java/org/zwobble/mammoth/Mammoth.java +++ b/src/main/java/org/zwobble/mammoth/Mammoth.java @@ -33,7 +33,7 @@ public class Mammoth { // TODO: prefix String idPrefix = "document"; return reader.readElement(documentXml) - .map(nodes -> new DocumentConverter(idPrefix).convertToHtml(nodes)) + .map(nodes -> DocumentConverter.convertToHtml(idPrefix, nodes)) .map(Html::write); } catch (IOException e) { throw new UnsupportedOperationException("Should return a result of failure"); diff --git a/src/main/java/org/zwobble/mammoth/documents/Note.java b/src/main/java/org/zwobble/mammoth/documents/Note.java index da6f68f..75c28c6 100644 --- a/src/main/java/org/zwobble/mammoth/documents/Note.java +++ b/src/main/java/org/zwobble/mammoth/documents/Note.java @@ -20,4 +20,8 @@ public class Note { public String getId() { return id; } + + public List<DocumentElement> getBody() { + return body; + } } diff --git a/src/main/java/org/zwobble/mammoth/documents/NoteReference.java b/src/main/java/org/zwobble/mammoth/documents/NoteReference.java index 01fff95..11190c3 100644 --- a/src/main/java/org/zwobble/mammoth/documents/NoteReference.java +++ b/src/main/java/org/zwobble/mammoth/documents/NoteReference.java @@ -17,6 +17,14 @@ public class NoteReference implements DocumentElement { this.noteId = noteId; } + public NoteType getNoteType() { + return noteType; + } + + public String getNoteId() { + return noteId; + } + @Override public <T> T accept(DocumentElementVisitor<T> visitor) { return visitor.visit(this); |
