diff --git a/src/org/fbreader/bookmodel/BookModel.java b/src/org/fbreader/bookmodel/BookModel.java index 035a60477..eea4a4003 100644 --- a/src/org/fbreader/bookmodel/BookModel.java +++ b/src/org/fbreader/bookmodel/BookModel.java @@ -3,6 +3,8 @@ package org.fbreader.bookmodel; import java.util.HashMap; import java.util.Map; +import org.zlibrary.text.model.ZLTextModel; +import org.zlibrary.text.model.ZLTextParagraph; import org.zlibrary.text.model.ZLTextPlainModel; import org.zlibrary.text.model.impl.ZLModelFactory; @@ -10,6 +12,18 @@ public class BookModel { private ZLTextPlainModel myBookModel = (new ZLModelFactory()).createPlainModel(); private Map myFootnotes = new HashMap(); + private Map myInternalHyperlinks = + new HashMap(); + + private class Label { + final int paragraphNumber; + final ZLTextModel model; + + Label(ZLTextModel model, int paragraph) { + paragraphNumber = paragraph; + this.model = model; + } + } public ZLTextPlainModel getBookModel() { return myBookModel; @@ -25,4 +39,17 @@ public class BookModel { public Map getFootnotes() { return myFootnotes; } + + public void addHyperlinkLabel(String label, ZLTextModel model, + int paragraphNumber) { + myInternalHyperlinks.put(label, new Label(model, paragraphNumber)); + } + + //tmp + public ZLTextParagraph getParagraphByLink(String link) { + if (myInternalHyperlinks.containsKey(link)) { + return myInternalHyperlinks.get(link).model.getParagraph(myInternalHyperlinks.get(link).paragraphNumber); + } + return null; + } } diff --git a/src/org/fbreader/bookmodel/BookReader.java b/src/org/fbreader/bookmodel/BookReader.java index 060efd47d..6a0faa428 100644 --- a/src/org/fbreader/bookmodel/BookReader.java +++ b/src/org/fbreader/bookmodel/BookReader.java @@ -113,4 +113,24 @@ public class BookReader { } } } + + public void addHyperlinkControl(Byte kind, String label) { + if (myTextParagraphExists) { + flushTextBufferToParagraph(); + myCurrentTextModel.addHyperlinkControl(kind, label); + } + myHyperlinkKind = kind; + myHyperlinkReference = label; + } + + public void addHyperlinkLabel(String label) { + if (myCurrentTextModel != null) { + int paragraphNumber = myCurrentTextModel.getParagraphsNumber(); + if (myTextParagraphExists) { + --paragraphNumber; + } + myBookModel.addHyperlinkLabel(label, myCurrentTextModel, paragraphNumber); + } + } + } diff --git a/src/org/fbreader/formats/fb2/FB2Handler.java b/src/org/fbreader/formats/fb2/FB2Handler.java index 2c023e868..b05e5ef68 100644 --- a/src/org/fbreader/formats/fb2/FB2Handler.java +++ b/src/org/fbreader/formats/fb2/FB2Handler.java @@ -7,7 +7,7 @@ import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import org.zlibrary.text.model.ZLTextParagraph; -class FB2Handler extends DefaultHandler { +class FB2Handler extends DefaultHandler { private BookReader myBookReader; private boolean myInsidePoem = false; @@ -17,6 +17,8 @@ class FB2Handler extends DefaultHandler { private int mySectionDepth = 0; private boolean mySectionStarted = false; + private byte myHyperlinkType; + private FB2Tag getTag(String s) { if (s.contains("-")) { s = s.replace('-', '_'); @@ -24,6 +26,15 @@ class FB2Handler extends DefaultHandler { return FB2Tag.valueOf(s.toUpperCase()); } + private String reference(Attributes attributes) { + int length = attributes.getLength(); + for (int i = 0; i < length; i++) { + if (attributes.getQName(i).endsWith(":href")) { + return attributes.getValue(i); + } + } + return ""; + } public FB2Handler(BookModel model) { myBookReader = new BookReader(model); @@ -102,6 +113,10 @@ class FB2Handler extends DefaultHandler { myReadMainText = false; myBookReader.unsetCurrentTextModel(); break; + + case A: + myBookReader.addControl(myHyperlinkType, false); + break; default: break; @@ -116,7 +131,7 @@ class FB2Handler extends DefaultHandler { if (!myReadMainText) { myBookReader.setFootnoteTextModel(id); } - // myModelReader.addHyperlinkLabel(id); + myBookReader.addHyperlinkLabel(id); } FB2Tag tag; try { @@ -206,6 +221,22 @@ class FB2Handler extends DefaultHandler { myReadMainText = true; } break; + + case A: + String ref = reference(attributes); + if (ref != "") { + if (ref.charAt(0) == '#') { + myHyperlinkType = (byte) FB2Tag.FOOTNOTE.ordinal(); + ref = ref.substring(1); + } else { + myHyperlinkType = (byte) FB2Tag.A.ordinal(); + } + myBookReader.addHyperlinkControl(myHyperlinkType, ref); + } else { + myHyperlinkType = (byte) FB2Tag.FOOTNOTE.ordinal(); + myBookReader.addControl(myHyperlinkType, true); + } + break; default: break; diff --git a/src/org/fbreader/formats/fb2/FB2Tag.java b/src/org/fbreader/formats/fb2/FB2Tag.java index 996c268f1..32bcd1a2e 100644 --- a/src/org/fbreader/formats/fb2/FB2Tag.java +++ b/src/org/fbreader/formats/fb2/FB2Tag.java @@ -22,5 +22,6 @@ public enum FB2Tag { CODE, STRIKETHROUGH, TITLE, - BODY; + BODY, + FOOTNOTE; } diff --git a/test/org/test/fbreader/formats/fb2/TestFB2Reader.java b/test/org/test/fbreader/formats/fb2/TestFB2Reader.java index ee287069a..4a1175ac3 100644 --- a/test/org/test/fbreader/formats/fb2/TestFB2Reader.java +++ b/test/org/test/fbreader/formats/fb2/TestFB2Reader.java @@ -1,9 +1,11 @@ package org.test.fbreader.formats.fb2; +import org.fbreader.bookmodel.BookModel; import org.fbreader.formats.fb2.FB2Reader; import org.fbreader.formats.fb2.FB2Tag; import org.zlibrary.text.model.ZLTextModel; import org.zlibrary.text.model.ZLTextParagraph; +import org.zlibrary.text.model.entry.ZLTextEntry; import junit.framework.TestCase; @@ -189,4 +191,27 @@ public class TestFB2Reader extends TestCase { assertEquals(model.dump(), "[PARAGRAPH]\n[CONTROL " + FB2Tag.SECTION.ordinal() + "][TEXT]Title[/TEXT][/PARAGRAPH]\n"); } + + public void testFootnote() { + FB2Reader reader = new FB2Reader("FB2ReaderTests/footnote.fb2"); + ZLTextModel model = reader.read().getBookModel(); + int footnote = FB2Tag.FOOTNOTE.ordinal(); + assertEquals(model.dump(), "[PARAGRAPH]\n[CONTROL " + footnote + + "][TEXT][1][/TEXT][/CONTROL " + footnote + "][/PARAGRAPH]\n"); + } + + public void testFootnote1() { + FB2Reader reader = new FB2Reader("FB2ReaderTests/footnote1.fb2"); + BookModel model = reader.read(); + assertEquals("footnote", + ((ZLTextEntry)model.getParagraphByLink("note1").getEntries().get(0)).getData()); + } + + public void testExternalHyperlink() { + FB2Reader reader = new FB2Reader("FB2ReaderTests/ext_hyperlink.fb2"); + ZLTextModel model = reader.read().getBookModel(); + int hyperlink = FB2Tag.A.ordinal(); + assertEquals(model.dump(), "[PARAGRAPH]\n[CONTROL " + hyperlink + + "][TEXT][1][/TEXT][/CONTROL " + hyperlink + "][/PARAGRAPH]\n"); + } }