Browse Source

Fix tag: <program-used>

Kandrashin Denis 12 years ago
parent
commit
e84a58386a
5 changed files with 98 additions and 95 deletions
  1. 57 78
      source/fb2html.cpp
  2. 2 4
      source/fb2html.h
  3. 23 9
      source/fb2save.cpp
  4. 10 0
      source/fb2save.hpp
  5. 6 4
      source/js/export.js

+ 57 - 78
source/fb2html.cpp

@@ -8,46 +8,48 @@
 
 FbTextElement::Scheme::Scheme()
 {
-    m_types["body"]
-        << Type("image")
-        << Type("title")
-        << Type("epigraph", 0, 0)
-        << Type()
-        << Type("section")
+    m_types["BODY"]
+        << Type("FB:DESCRIPTION", 1, 1)
+        << Type("FB:BODY", 1, 1)
     ;
 
-    m_types["section"]
-        << Type("title")
-        << Type("epigraph", 0, 0)
-        << Type("image")
-        << Type("annotation")
-        << Type()
-        << Type("section")
+    m_types["FB:DESCRIPTION"]
+        << Type("FB:TITLE-INFO", 1, 1)
+        << Type("FB:SRC-TITLE-INFO", 0, 1)
+        << Type("FB:DOCUMENT-INFO", 1, 1)
+        << Type("FB:PUBLISH-INFO", 0, 1)
+        << Type("FB:CUSTOM-INFO")
     ;
 
-    m_types["poem"]
-        << Type("title")
-        << Type("epigraph", 0, 0)
-        << Type("stanza", 1, 0)
-        << Type()
-        << Type("text-author", 0, 0)
-        << Type("date")
+    m_types["FB:DOCUMENT-INFO"]
+        << Type("FB:AUTHOR", 1, 1)
+        << Type("FB:PROGRAM-USED", 0, 1)
+        << Type("FB:DATE", 0, 1)
     ;
 
-    m_types["stanza"]
-        << Type("title")
-        << Type("subtitle")
-        << Type()
+    m_types["FB:BODY"]
+        << Type("IMG")
+        << Type("FB:TITLE", 0, 1)
+        << Type("FB:EPIGRAPH")
+        << Type("FB:SECTION", 1, 0)
     ;
 
-    m_types["epigraph"]
-        << Type()
-        << Type("text-author", 0, 0)
+    m_types["FB:SECTION"]
+        << Type("FB:TITLE", 1, 0)
+        << Type("FB:EPIGRAPH")
+        << Type("IMG")
+        << Type("FB:ANNOTATION")
+        << Type("FB:SECTION")
     ;
 
-    m_types["cite"]
-        << Type()
-        << Type("text-author", 0, 0)
+    m_types["FB:POEM"]
+        << Type("FB:TITLE", 1, 0)
+        << Type("FB:EPIGRAPH", 0, 0)
+        << Type("FB:STANZA", 1, 0)
+    ;
+
+    m_types["FB:STANZA"]
+        << Type("FB:TITLE", 1, 0)
     ;
 }
 
@@ -69,10 +71,8 @@ FbTextElement::Sublist::Sublist(const TypeList &list, const QString &name)
     TypeList::const_iterator empty = list.end();
     while (m_pos != list.end()) {
         if (m_pos->name() == name) break;
-        if (m_pos->name().isEmpty()) empty = m_pos;
         m_pos++;
     }
-    if (m_pos == list.end()) m_pos = empty;
 }
 
 FbTextElement::Sublist::operator bool() const
@@ -87,47 +87,27 @@ bool FbTextElement::Sublist::operator!() const
 
 bool FbTextElement::Sublist::operator <(const FbTextElement &element) const
 {
+    if (element.isNull()) return true;
     const QString name = element.nodeName();
     for (TypeList::const_iterator it = m_list.begin(); it != m_list.end(); it++) {
-        if (it->name() == name) return m_pos < it  || element.isNull();
-    }
-    return false;
-}
-
-bool FbTextElement::Sublist::operator >=(const FbTextElement &element) const
-{
-    const QString name = element.nodeName();
-    for (TypeList::const_iterator it = m_list.begin(); it != m_list.end(); it++) {
-        if (it->name() == name) return m_pos >= it || element.isNull();
+        if (it->name() == name) return m_pos < it;
     }
     return false;
 }
 
-bool FbTextElement::Sublist::operator !=(const FbTextElement &element) const
-{
-    return element.isNull() || m_pos->name() != element.nodeName();
-}
-
 //---------------------------------------------------------------------------
 //  FbTextElement
 //---------------------------------------------------------------------------
 
 FbTextElement FbTextElement::operator[](const QString &name)
 {
+    QString tagName = name.toUpper();
     FbTextElement child = firstChild();
     while (!child.isNull()) {
-        if (child.tagName().toLower() == name) return child;
+        if (child.tagName() == tagName) return child;
         child = child.nextSibling();
     }
-    QString html = QString("<%1></%1>").arg(name);
-    appendInside(html);
-    return lastChild();
-}
-
-QString FbTextElement::blockName() const
-{
-    QString n = tagName().toLower();
-    return n.left(3) == "fb:" ? n.mid(3) : QString();
+    return insertInside(tagName, QString("<%1></%1>").arg(name));
 }
 
 QString FbTextElement::nodeName() const
@@ -140,12 +120,12 @@ void FbTextElement::getChildren(FbElementList &list)
 {
     FbTextElement child = firstChild();
     while (!child.isNull()) {
-        QString tag = child.tagName().toLower();
-        if (tag == "fb:description") {
+        QString tag = child.tagName();
+        if (tag == "FB:DESCRIPTION") {
             // skip description
-        } else if (tag.left(3) == "fb:") {
+        } else if (tag.left(3) == "FB:") {
             list << child;
-        } else if (tag == "img") {
+        } else if (tag == "IMG") {
             list << child;
         } else {
             child.getChildren(list);
@@ -176,7 +156,7 @@ bool FbTextElement::hasScheme() const
 const FbTextElement::TypeList * FbTextElement::subtypes() const
 {
     static Scheme scheme;
-    return scheme[nodeName()];
+    return scheme[tagName()];
 }
 
 bool FbTextElement::hasSubtype(const QString &style) const
@@ -203,24 +183,23 @@ FbTextElement FbTextElement::insertInside(const QString &style, const QString &h
     if (!types) return FbTextElement();
 
     Sublist sublist(*types, style);
-    if (!sublist) return FbTextElement();
-
-    FbTextElement child = firstChild();
-    if (sublist < child) {
-        prependInside(html);
-        return firstChild();
-    }
-
-    while (!child.isNull()) {
-        FbTextElement subling = child.nextSibling();
-        if (sublist >= child && sublist != subling) {
-            child.appendOutside(html);
-            return child.nextSibling();
+    if (sublist) {
+        FbTextElement child = firstChild();
+        if (sublist < child) {
+            prependInside(html);
+            return firstChild();
+        }
+        while (!child.isNull()) {
+            FbTextElement subling = child.nextSibling();
+            if (sublist < subling) {
+                child.appendOutside(html);
+                return child.nextSibling();
+            }
+            child = subling;
         }
-        child = subling;
     }
-
-    return FbTextElement();
+    appendInside(html);
+    return lastChild();
 }
 
 QString FbTextElement::location()

+ 2 - 4
source/fb2html.h

@@ -16,7 +16,8 @@ private:
     class Type
     {
     public:
-        Type(const QString &name = QString(), int min=0, int max=1): m_name(name), m_min(min), m_max(max) {}
+        Type(const QString &name): m_name(name), m_min(0), m_max(0) {}
+        Type(const QString &name, int min, int max): m_name(name), m_min(min), m_max(max) {}
         Type(const Type &t): m_name(t.m_name), m_min(t.m_min), m_max(t.m_max) {}
         const QString & name() const { return m_name; }
         int min() const { return m_min; }
@@ -47,8 +48,6 @@ private:
         operator bool() const;
         bool operator !() const;
         bool operator <(const FbTextElement &element) const;
-        bool operator >=(const FbTextElement &element) const;
-        bool operator !=(const FbTextElement &element) const;
     private:
         const TypeList &m_list;
         TypeList::const_iterator m_pos;
@@ -60,7 +59,6 @@ public:
     FbTextElement &operator=(const QWebElement &x) { QWebElement::operator=(x); return *this; }
     FbTextElement insertInside(const QString &style, const QString &html);
     FbTextElement child(int index) const;
-    QString blockName() const;
     QString nodeName() const;
     void getChildren(FbElementList &list);
     bool hasSubtype(const QString &style) const;

+ 23 - 9
source/fb2save.cpp

@@ -375,6 +375,21 @@ int FbSaveHandler::TextHandler::nextLevel() const
     return m_level ? m_level + 1 : 0;
 }
 
+//---------------------------------------------------------------------------
+//  FbSaveHandler::RootHandler
+//---------------------------------------------------------------------------
+
+FbSaveHandler::RootHandler::RootHandler(FbSaveWriter &writer, const QString &name)
+    : NodeHandler(name)
+    , m_writer(writer)
+{
+}
+
+FbXmlHandler::NodeHandler * FbSaveHandler::RootHandler::NewTag(const QString &name, const QXmlAttributes &atts)
+{
+    return name == "body" ? new BodyHandler(m_writer, name, atts) : NULL;
+}
+
 //---------------------------------------------------------------------------
 //  FbSaveHandler::BodyHandler
 //---------------------------------------------------------------------------
@@ -478,8 +493,8 @@ bool FbSaveHandler::comment(const QString& ch)
 FbXmlHandler::NodeHandler * FbSaveHandler::CreateRoot(const QString &name, const QXmlAttributes &atts)
 {
     Q_UNUSED(atts);
-    if (name == "body") return new BodyHandler(m_writer, name, atts);
-    m_error = QObject::tr("The tag <body> was not found.");
+    if (name == "html") return new RootHandler(m_writer, name);
+    m_error = QObject::tr("The tag <html> was not found.");
     return 0;
 }
 
@@ -490,14 +505,14 @@ void FbSaveHandler::setDocumentInfo(QWebFrame * frame)
     QString info2 = now.toString("dd MMM yyyy");
     QString value = now.toString("yyyy-MM-dd hh:mm:ss");
 
-    FbTextElement parent = frame->documentElement().findFirst("body");
-    parent = parent["fb:description"];
-    parent = parent["fb:document-info"];
+    FbTextElement parent = frame->documentElement().findFirst("BODY");
+    parent = parent["FB:DESCRIPTION"];
+    parent = parent["FB:DOCUMENT-INFO"];
 
-    FbTextElement child1 = parent["fb:program-used"];
+    FbTextElement child1 = parent["FB:PROGRAM-USED"];
     child1.setInnerXml(info1);
 
-    FbTextElement child2 = parent["fb:date"];
+    FbTextElement child2 = parent["FB:DATE"];
     child2.setInnerXml(info2);
     child2.setAttribute("value", value);
 }
@@ -514,8 +529,7 @@ bool FbSaveHandler::save()
     m_writer.writeStartDocument();
     QString javascript = jScript("export.js");
     frame->addToJavaScriptWindowObject("handler", this);
-    QWebElement body = frame->findFirstElement("body");
-    body.evaluateJavaScript(javascript);
+    frame->evaluateJavaScript(javascript);
     m_writer.writeEndDocument();
 
     return true;

+ 10 - 0
source/fb2save.hpp

@@ -129,6 +129,16 @@ private:
         bool m_hasChild;
     };
 
+    class RootHandler : public NodeHandler
+    {
+    public:
+        explicit RootHandler(FbSaveWriter &writer, const QString &name);
+    protected:
+        virtual NodeHandler * NewTag(const QString &name, const QXmlAttributes &atts);
+    protected:
+        FbSaveWriter &m_writer;
+    };
+
     class BodyHandler : public TextHandler
     {
     public:

+ 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);
     }
-})(this);
+})(document);