Browse Source

Use FB2 comments

Kandrashin Denis 13 years ago
parent
commit
aa05c872c0
10 changed files with 127 additions and 74 deletions
  1. 4 3
      source/fb2code.hpp
  2. 1 1
      source/fb2main.cpp
  3. 22 11
      source/fb2read.cpp
  4. 2 0
      source/fb2read.hpp
  5. 57 36
      source/fb2save.cpp
  6. 26 16
      source/fb2save.hpp
  7. 2 2
      source/fb2view.cpp
  8. 1 1
      source/fb2view.hpp
  9. 6 0
      source/fb2xml2.cpp
  10. 6 4
      source/js/export.js

+ 4 - 3
source/fb2code.hpp

@@ -114,9 +114,8 @@ public:
 
     QString text() const { return toPlainText(); }
 
-    bool read(QIODevice *device) { return true; }
-
-    void zoomTo ( int size ) {}
+    bool read(QIODevice *device)
+        { Q_UNUSED(device); return true; }
 
     void load(const QByteArray data, const QList<int> folds)
         { setPlainText(QString::fromUtf8(data.data())); }
@@ -125,6 +124,8 @@ public:
 
     bool isRedoAvailable() { return false; }
 
+    void zoomTo ( int size ) {}
+
 public slots:
     void zoomIn();
     void zoomOut();

+ 1 - 1
source/fb2main.cpp

@@ -591,7 +591,7 @@ void Fb2MainWindow::viewCode()
     QByteArray xml;
     QList<int> folds;
     if (textEdit) {
-        textEdit->save(&xml, &folds);
+        textEdit->save(&xml);
         load = true;
     }
 

+ 22 - 11
source/fb2read.cpp

@@ -43,6 +43,7 @@ bool Fb2ReadThread::parse()
     Fb2ReadHandler handler(*this, writer);
     XML2::XmlReader reader;
     reader.setContentHandler(&handler);
+    reader.setLexicalHandler(&handler);
     reader.setErrorHandler(&handler);
     if (m_xml.isEmpty()) {
         QFile file(m_filename);
@@ -66,6 +67,7 @@ bool Fb2ReadThread::parse()
     Fb2ReadHandler handler(*this, writer);
     QXmlSimpleReader reader;
     reader.setContentHandler(&handler);
+    reader.setLexicalHandler(&handler);
     reader.setErrorHandler(&handler);
     QXmlInputSource source;
     if (m_xml.isEmpty()) {
@@ -97,15 +99,6 @@ FB2_END_KEYHASH
 Fb2ReadHandler::RootHandler::RootHandler(Fb2ReadHandler &owner, const QString &name)
     : BaseHandler(owner, name)
 {
-    writer().writeStartDocument();
-    writer().writeStartElement("html");
-    writer().writeStartElement("head");
-    writer().writeStartElement("script");
-    writer().writeAttribute("type", "text/javascript");
-    writer().writeAttribute("src", "qrc:/js/jquery.js");
-    writer().writeCharacters(" ");
-    writer().writeEndElement();
-    writer().writeEndElement();
     writer().writeStartElement("body");
 }
 
@@ -123,8 +116,6 @@ void Fb2ReadHandler::RootHandler::EndTag(const QString &name)
 {
     Q_UNUSED(name);
     writer().writeEndElement();
-    writer().writeEndElement();
-    writer().writeEndDocument();
 }
 
 //---------------------------------------------------------------------------
@@ -367,6 +358,20 @@ Fb2ReadHandler::Fb2ReadHandler(Fb2ReadThread &thread, QXmlStreamWriter &writer)
 {
     m_writer.setAutoFormatting(true);
     m_writer.setAutoFormattingIndent(2);
+
+    m_writer.writeStartElement("html");
+    m_writer.writeStartElement("head");
+    m_writer.writeStartElement("script");
+    m_writer.writeAttribute("type", "text/javascript");
+    m_writer.writeAttribute("src", "qrc:/js/jquery.js");
+    m_writer.writeCharacters(" ");
+    m_writer.writeEndElement();
+    m_writer.writeEndElement();
+}
+
+Fb2ReadHandler::~Fb2ReadHandler()
+{
+    m_writer.writeEndElement();
 }
 
 Fb2XmlHandler::NodeHandler * Fb2ReadHandler::CreateRoot(const QString &name, const QXmlAttributes &atts)
@@ -377,6 +382,12 @@ Fb2XmlHandler::NodeHandler * Fb2ReadHandler::CreateRoot(const QString &name, con
     return 0;
 }
 
+bool Fb2ReadHandler::comment(const QString& ch)
+{
+    m_writer.writeComment(ch);
+    return true;
+}
+
 QString Fb2ReadHandler::getFile(const QString &name)
 {
     QString path;

+ 2 - 0
source/fb2read.hpp

@@ -40,6 +40,8 @@ class Fb2ReadHandler : public Fb2XmlHandler
 {
 public:
     explicit Fb2ReadHandler(Fb2ReadThread &thread, QXmlStreamWriter &writer);
+    virtual ~Fb2ReadHandler();
+    virtual bool comment(const QString& ch);
     Fb2ReadThread & thread() { return m_thread; }
     QXmlStreamWriter & writer() { return m_writer; }
 

+ 57 - 36
source/fb2save.cpp

@@ -119,7 +119,7 @@ void Fb2HtmlHandler::onTxt(const QString &text)
 
 void Fb2HtmlHandler::onCom(const QString &text)
 {
-    Q_UNUSED(text);
+    comment(text);
 }
 
 void Fb2HtmlHandler::onEnd(const QString &name)
@@ -131,30 +131,31 @@ void Fb2HtmlHandler::onEnd(const QString &name)
 //  Fb2SaveWriter
 //---------------------------------------------------------------------------
 
-Fb2SaveWriter::Fb2SaveWriter(Fb2WebView &view, QByteArray *array, QList<int> *folds)
+Fb2SaveWriter::Fb2SaveWriter(Fb2WebView &view, QByteArray *array)
     : QXmlStreamWriter(array)
-    , m_folds(folds)
     , m_view(view)
-    , m_line(0)
 {
 }
 
-Fb2SaveWriter::Fb2SaveWriter(Fb2WebView &view, QIODevice *device, QList<int> *folds)
+Fb2SaveWriter::Fb2SaveWriter(Fb2WebView &view, QIODevice *device)
     : QXmlStreamWriter(device)
-    , m_folds(folds)
     , m_view(view)
-    , m_line(0)
 {
 }
 
-Fb2SaveWriter::Fb2SaveWriter(Fb2WebView &view, QString *string, QList<int> *folds)
+Fb2SaveWriter::Fb2SaveWriter(Fb2WebView &view, QString *string)
     : QXmlStreamWriter(string)
-    , m_folds(folds)
     , m_view(view)
-    , m_line(0)
 {
 }
 
+void Fb2SaveWriter::writeComment(const QString &ch)
+{
+    writeLineEnd();
+    QXmlStreamWriter::writeComment(ch);
+
+}
+
 void Fb2SaveWriter::writeStartElement(const QString &name, int level)
 {
     if (level) writeLineEnd();
@@ -172,7 +173,6 @@ void Fb2SaveWriter::writeEndElement(int level)
 void Fb2SaveWriter::writeLineEnd()
 {
     writeCharacters("\n");
-    m_line++;
 }
 
 QByteArray Fb2SaveWriter::downloadFile(const QUrl &url)
@@ -219,7 +219,6 @@ void Fb2SaveWriter::writeFiles()
         QString type = file->type();
         QString data = file->data().toBase64();
         writeStartElement("binary", 2);
-        if (m_folds) m_folds->append(m_line);
         writeAttribute("id", name);
         if (!type.isEmpty()) writeAttribute("content-type", type);
         writeLineEnd();
@@ -237,10 +236,10 @@ void Fb2SaveWriter::writeFiles()
 }
 
 //---------------------------------------------------------------------------
-//  Fb2SaveHandler::BodyHandler
+//  Fb2SaveHandler::TextHandler
 //---------------------------------------------------------------------------
 
-FB2_BEGIN_KEYHASH(Fb2SaveHandler::BodyHandler)
+FB2_BEGIN_KEYHASH(Fb2SaveHandler::TextHandler)
     FB2_KEY( Section , "div"    );
     FB2_KEY( Anchor  , "a"      );
     FB2_KEY( Image   , "img"  );
@@ -254,7 +253,7 @@ FB2_BEGIN_KEYHASH(Fb2SaveHandler::BodyHandler)
     FB2_KEY( Code    , "tt"     );
 FB2_END_KEYHASH
 
-Fb2SaveHandler::BodyHandler::BodyHandler(Fb2SaveWriter &writer, const QString &name, const QXmlAttributes &atts, const QString &tag)
+Fb2SaveHandler::TextHandler::TextHandler(Fb2SaveWriter &writer, const QString &name, const QXmlAttributes &atts, const QString &tag)
     : NodeHandler(name)
     , m_writer(writer)
     , m_tag(tag)
@@ -264,7 +263,7 @@ Fb2SaveHandler::BodyHandler::BodyHandler(Fb2SaveWriter &writer, const QString &n
     Init(atts);
 }
 
-Fb2SaveHandler::BodyHandler::BodyHandler(BodyHandler *parent, const QString &name, const QXmlAttributes &atts, const QString &tag)
+Fb2SaveHandler::TextHandler::TextHandler(TextHandler *parent, const QString &name, const QXmlAttributes &atts, const QString &tag)
     : NodeHandler(name)
     , m_writer(parent->m_writer)
     , m_tag(tag)
@@ -274,7 +273,7 @@ Fb2SaveHandler::BodyHandler::BodyHandler(BodyHandler *parent, const QString &nam
     Init(atts);
 }
 
-void Fb2SaveHandler::BodyHandler::Init(const QXmlAttributes &atts)
+void Fb2SaveHandler::TextHandler::Init(const QXmlAttributes &atts)
 {
     if (m_tag.isEmpty()) return;
     m_writer.writeStartElement(m_tag, m_level);
@@ -291,7 +290,7 @@ void Fb2SaveHandler::BodyHandler::Init(const QXmlAttributes &atts)
     }
 }
 
-Fb2XmlHandler::NodeHandler * Fb2SaveHandler::BodyHandler::NewTag(const QString &name, const QXmlAttributes &atts)
+Fb2XmlHandler::NodeHandler * Fb2SaveHandler::TextHandler::NewTag(const QString &name, const QXmlAttributes &atts)
 {
     m_hasChild = true;
     QString tag = QString();
@@ -308,22 +307,22 @@ Fb2XmlHandler::NodeHandler * Fb2SaveHandler::BodyHandler::NewTag(const QString &
         case Sup       : tag = "sup"           ; break;
         default: ;
     }
-    return new BodyHandler(this, name, atts, tag);
+    return new TextHandler(this, name, atts, tag);
 }
 
-void Fb2SaveHandler::BodyHandler::TxtTag(const QString &text)
+void Fb2SaveHandler::TextHandler::TxtTag(const QString &text)
 {
     m_writer.writeCharacters(text);
 }
 
-void Fb2SaveHandler::BodyHandler::EndTag(const QString &name)
+void Fb2SaveHandler::TextHandler::EndTag(const QString &name)
 {
     Q_UNUSED(name);
     if (m_tag.isEmpty()) return;
     m_writer.writeEndElement(m_hasChild ? m_level : 0);
 }
 
-int Fb2SaveHandler::BodyHandler::nextLevel() const
+int Fb2SaveHandler::TextHandler::nextLevel() const
 {
     return m_level ? m_level + 1 : 0;
 }
@@ -332,25 +331,40 @@ int Fb2SaveHandler::BodyHandler::nextLevel() const
 //  Fb2SaveHandler::RootHandler
 //---------------------------------------------------------------------------
 
-Fb2SaveHandler::RootHandler::RootHandler(Fb2SaveWriter &writer, const QString &name, const QXmlAttributes &atts)
-    : BodyHandler(writer, name, atts, "FictionBook")
+Fb2SaveHandler::RootHandler::RootHandler(Fb2SaveWriter &writer, const QString &name)
+    : NodeHandler(name)
+    , m_writer(writer)
+{
+}
+
+Fb2XmlHandler::NodeHandler * Fb2SaveHandler::RootHandler::NewTag(const QString &name, const QXmlAttributes &atts)
+{
+    return name == "body" ? new BodyHandler(m_writer, name, atts) : NULL;
+}
+
+//---------------------------------------------------------------------------
+//  Fb2SaveHandler::BodyHandler
+//---------------------------------------------------------------------------
+
+Fb2SaveHandler::BodyHandler::BodyHandler(Fb2SaveWriter &writer, const QString &name, const QXmlAttributes &atts)
+    : TextHandler(writer, name, atts, "FictionBook")
 {
     m_writer.writeAttribute("xmlns", "http://www.gribuser.ru/xml/fictionbook/2.0");
     m_writer.writeAttribute("xmlns:l", "http://www.w3.org/1999/xlink");
 }
 
-void Fb2SaveHandler::RootHandler::EndTag(const QString &name)
+void Fb2SaveHandler::BodyHandler::EndTag(const QString &name)
 {
     m_writer.writeFiles();
-    BodyHandler::EndTag(name);
+    TextHandler::EndTag(name);
 }
 
 //---------------------------------------------------------------------------
 //  Fb2SaveHandler::AnchorHandler
 //---------------------------------------------------------------------------
 
-Fb2SaveHandler::AnchorHandler::AnchorHandler(BodyHandler *parent, const QString &name, const QXmlAttributes &atts)
-    : BodyHandler(parent, name, atts, "a")
+Fb2SaveHandler::AnchorHandler::AnchorHandler(TextHandler *parent, const QString &name, const QXmlAttributes &atts)
+    : TextHandler(parent, name, atts, "a")
 {
     QString href = Value(atts, "href");
     m_writer.writeAttribute("l:href", href);
@@ -360,8 +374,8 @@ Fb2SaveHandler::AnchorHandler::AnchorHandler(BodyHandler *parent, const QString
 //  Fb2SaveHandler::ImageHandler
 //---------------------------------------------------------------------------
 
-Fb2SaveHandler::ImageHandler::ImageHandler(BodyHandler *parent, const QString &name, const QXmlAttributes &atts)
-    : BodyHandler(parent, name, atts, "image")
+Fb2SaveHandler::ImageHandler::ImageHandler(TextHandler *parent, const QString &name, const QXmlAttributes &atts)
+    : TextHandler(parent, name, atts, "image")
 {
     QString src = Value(atts, "src");
     QString file = m_writer.getFileName(src);
@@ -374,8 +388,8 @@ Fb2SaveHandler::ImageHandler::ImageHandler(BodyHandler *parent, const QString &n
 //  Fb2SaveHandler::ParagHandler
 //---------------------------------------------------------------------------
 
-Fb2SaveHandler::ParagHandler::ParagHandler(BodyHandler *parent, const QString &name, const QXmlAttributes &atts)
-    : BodyHandler(parent, name, atts, "")
+Fb2SaveHandler::ParagHandler::ParagHandler(TextHandler *parent, const QString &name, const QXmlAttributes &atts)
+    : TextHandler(parent, name, atts, "")
     , m_parent(parent->tag())
     , m_empty(true)
 {
@@ -384,7 +398,7 @@ Fb2SaveHandler::ParagHandler::ParagHandler(BodyHandler *parent, const QString &n
 Fb2XmlHandler::NodeHandler * Fb2SaveHandler::ParagHandler::NewTag(const QString &name, const QXmlAttributes &atts)
 {
     if (m_empty) start();
-    return BodyHandler::NewTag(name, atts);
+    return TextHandler::NewTag(name, atts);
 }
 
 void Fb2SaveHandler::ParagHandler::TxtTag(const QString &text)
@@ -393,7 +407,7 @@ void Fb2SaveHandler::ParagHandler::TxtTag(const QString &text)
         if (isWhiteSpace(text)) return;
         start();
     }
-    BodyHandler::TxtTag(text);
+    TextHandler::TxtTag(text);
 }
 
 void Fb2SaveHandler::ParagHandler::EndTag(const QString &name)
@@ -421,10 +435,17 @@ Fb2SaveHandler::Fb2SaveHandler(Fb2SaveWriter &writer)
 {
 }
 
+bool Fb2SaveHandler::comment(const QString& ch)
+{
+    m_writer.writeComment(ch);
+    return true;
+}
+
 Fb2XmlHandler::NodeHandler * Fb2SaveHandler::CreateRoot(const QString &name, const QXmlAttributes &atts)
 {
-    if (name == "body") return new RootHandler(m_writer, name, atts);
-    m_error = QObject::tr("The tag <body> was not found.");
+    Q_UNUSED(atts);
+    if (name == "html") return new RootHandler(m_writer, name);
+    m_error = QObject::tr("The tag <html> was not found.");
     return 0;
 }
 

+ 26 - 16
source/fb2save.hpp

@@ -66,32 +66,32 @@ private:
 class Fb2SaveWriter : public QXmlStreamWriter
 {
 public:
-    explicit Fb2SaveWriter(Fb2WebView &view, QByteArray *array, QList<int> *folds = 0);
-    explicit Fb2SaveWriter(Fb2WebView &view, QIODevice *device, QList<int> *folds = 0);
-    explicit Fb2SaveWriter(Fb2WebView &view, QString *string, QList<int> *folds = 0);
+    explicit Fb2SaveWriter(Fb2WebView &view, QByteArray *array);
+    explicit Fb2SaveWriter(Fb2WebView &view, QIODevice *device);
+    explicit Fb2SaveWriter(Fb2WebView &view, QString *string);
     Fb2WebView & view() { return m_view; }
     QString getFileName(const QString &src);
     void writeStartElement(const QString &name, int level);
     void writeEndElement(int level);
+    void writeComment(const QString &ch);
     void writeLineEnd();
     void writeFiles();
 private:
     QByteArray downloadFile(const QUrl &url);
 private:
-    QList<int> *m_folds;
     Fb2WebView &m_view;
     QStringList m_names;
-    int m_line;
 };
 
 class Fb2SaveHandler : public Fb2HtmlHandler
 {
 public:
     explicit Fb2SaveHandler(Fb2SaveWriter &writer);
+    virtual bool comment(const QString& ch);
     bool save();
 
 private:
-    class BodyHandler : public NodeHandler
+    class TextHandler : public NodeHandler
     {
         FB2_BEGIN_KEYLIST
             Section,
@@ -107,8 +107,8 @@ private:
             Code,
        FB2_END_KEYLIST
     public:
-        explicit BodyHandler(Fb2SaveWriter &writer, const QString &name, const QXmlAttributes &atts, const QString &tag);
-        explicit BodyHandler(BodyHandler *parent, const QString &name, const QXmlAttributes &atts, const QString &tag);
+        explicit TextHandler(Fb2SaveWriter &writer, const QString &name, const QXmlAttributes &atts, const QString &tag);
+        explicit TextHandler(TextHandler *parent, const QString &name, const QXmlAttributes &atts, const QString &tag);
         const QString & tag() { return m_tag; }
     protected:
         virtual NodeHandler * NewTag(const QString &name, const QXmlAttributes &atts);
@@ -125,32 +125,42 @@ private:
         bool m_hasChild;
     };
 
-    class RootHandler : public BodyHandler
+    class RootHandler : public NodeHandler
     {
     public:
-        explicit RootHandler(Fb2SaveWriter &writer, const QString &name, const QXmlAttributes &atts);
+        explicit RootHandler(Fb2SaveWriter &writer, const QString &name);
+    protected:
+        virtual NodeHandler * NewTag(const QString &name, const QXmlAttributes &atts);
+    protected:
+        Fb2SaveWriter &m_writer;
+    };
+
+    class BodyHandler : public TextHandler
+    {
+    public:
+        explicit BodyHandler(Fb2SaveWriter &writer, const QString &name, const QXmlAttributes &atts);
     protected:
         virtual void EndTag(const QString &name);
     };
 
-    class AnchorHandler : public BodyHandler
+    class AnchorHandler : public TextHandler
     {
     public:
-        explicit AnchorHandler(BodyHandler *parent, const QString &name, const QXmlAttributes &atts);
+        explicit AnchorHandler(TextHandler *parent, const QString &name, const QXmlAttributes &atts);
     };
 
-    class ImageHandler : public BodyHandler
+    class ImageHandler : public TextHandler
     {
     public:
-        explicit ImageHandler(BodyHandler *parent, const QString &name, const QXmlAttributes &atts);
+        explicit ImageHandler(TextHandler *parent, const QString &name, const QXmlAttributes &atts);
     protected:
         virtual void EndTag(const QString &name) { Q_UNUSED(name); }
     };
 
-    class ParagHandler : public BodyHandler
+    class ParagHandler : public TextHandler
     {
     public:
-        explicit ParagHandler(BodyHandler *parent, const QString &name, const QXmlAttributes &atts);
+        explicit ParagHandler(TextHandler *parent, const QString &name, const QXmlAttributes &atts);
     protected:
         virtual NodeHandler * NewTag(const QString &name, const QXmlAttributes &atts);
         virtual void TxtTag(const QString &text);

+ 2 - 2
source/fb2view.cpp

@@ -182,9 +182,9 @@ bool Fb2WebView::save(QIODevice *device, const QString &codec)
     return Fb2SaveHandler(writer).save();
 }
 
-bool Fb2WebView::save(QByteArray *array, QList<int> *folds)
+bool Fb2WebView::save(QByteArray *array)
 {
-    Fb2SaveWriter writer(*this, array, folds);
+    Fb2SaveWriter writer(*this, array);
     return Fb2SaveHandler(writer).save();
 }
 

+ 1 - 1
source/fb2view.hpp

@@ -67,7 +67,7 @@ public:
     Fb2TemporaryList & files() { return m_files; }
     void load(const QString &filename, const QString &xml = QString());
     bool save(QIODevice *device, const QString &codec = QString());
-    bool save(QByteArray *array, QList<int> *folds = 0);
+    bool save(QByteArray *array);
     bool save(QString *string);
     QString toBodyXml();
     QString status();

+ 6 - 0
source/fb2xml2.cpp

@@ -468,6 +468,12 @@ void XmlReaderPrivate::process(xmlTextReaderPtr reader)
             QString qName = C2S(xmlTextReaderConstName(reader));
             contenthandler->endElement("", localName, qName);
         } break;
+        case XML_READER_TYPE_COMMENT: {
+            if (lexicalhandler) {
+                QString value = C2S(xmlTextReaderConstValue(reader));
+                lexicalhandler->comment(value);
+            }
+        } break;
     }
 }
 

+ 6 - 4
source/js/export.js

@@ -4,11 +4,13 @@
     } else if (node.nodeName === "#comment") {
         handler.onCom(node.data);
     } else {
-        var atts = node.attributes;
-        var count = atts.length;
-        for (var i = 0; i < count; i++) handler.onAttr(atts[i].name, atts[i].value);
+        if (node.nodeName !== "#document") {
+            var atts = node.attributes;
+            var count = atts.length;
+            for (var i = 0; i < count; i++) handler.onAttr(atts[i].name, atts[i].value);
+        }
         handler.onNew(node.nodeName);
         for (var n = node.firstChild; n !== null; n = n.nextSibling) f(n);
         handler.onEnd(node.nodeName);
     }
-})(document.body);
+})(document);