[Libreoffice-commits] core.git: test/source writerperfect/qa writerperfect/source

Miklos Vajna vmiklos at collabora.co.uk
Fri Sep 8 15:56:43 UTC 2017


 test/source/xmltesttools.cxx                                      |    1 
 writerperfect/qa/unit/EPUBExportTest.cxx                          |   21 ++
 writerperfect/qa/unit/data/writer/epubexport/para-char-props.fodt |   16 ++
 writerperfect/source/writer/exp/txtparai.cxx                      |   79 ++++++----
 writerperfect/source/writer/exp/txtparai.hxx                      |    4 
 5 files changed, 87 insertions(+), 34 deletions(-)

New commits:
commit 687fdc5750ac756f157c663197b998eb471612ef
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Fri Sep 8 15:55:03 2017 +0200

    EPUB export: inherit text properties in spans from paragraph
    
    This is similar to nested spans, but here the outer element is a
    paragraph.
    
    Change-Id: Ibcdfe5aac54a44797067b06d319d19d2d47d5dd1
    Reviewed-on: https://gerrit.libreoffice.org/42104
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>

diff --git a/test/source/xmltesttools.cxx b/test/source/xmltesttools.cxx
index 04e90f3cbd7e..659af490f053 100644
--- a/test/source/xmltesttools.cxx
+++ b/test/source/xmltesttools.cxx
@@ -64,6 +64,7 @@ void XmlTestTools::registerNamespaces(xmlXPathContextPtr& /*pXmlXpathCtx*/)
 
 OUString XmlTestTools::getXPath(xmlDocPtr pXmlDoc, const OString& rXPath, const OString& rAttribute)
 {
+    CPPUNIT_ASSERT(pXmlDoc);
     xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, rXPath);
     xmlNodeSetPtr pXmlNodes = pXmlObj->nodesetval;
     CPPUNIT_ASSERT_EQUAL_MESSAGE(OString("In <" + OString(pXmlDoc->name) + ">, XPath '" + rXPath + "' number of nodes is incorrect").getStr(),
diff --git a/writerperfect/qa/unit/EPUBExportTest.cxx b/writerperfect/qa/unit/EPUBExportTest.cxx
index 10fd5eb5a94a..06278d19eb81 100644
--- a/writerperfect/qa/unit/EPUBExportTest.cxx
+++ b/writerperfect/qa/unit/EPUBExportTest.cxx
@@ -64,6 +64,7 @@ public:
     void testNestedSpan();
     void testLineBreak();
     void testEscape();
+    void testParaCharProps();
 
     CPPUNIT_TEST_SUITE(EPUBExportTest);
     CPPUNIT_TEST(testOutlineLevel);
@@ -79,6 +80,7 @@ public:
     CPPUNIT_TEST(testNestedSpan);
     CPPUNIT_TEST(testLineBreak);
     CPPUNIT_TEST(testEscape);
+    CPPUNIT_TEST(testParaCharProps);
     CPPUNIT_TEST_SUITE_END();
 };
 
@@ -327,9 +329,9 @@ void EPUBExportTest::testLineBreak()
 
     mpXmlDoc = parseExport("OEBPS/sections/section0001.xhtml");
     // This was 0, line break was not handled.
-    assertXPath(mpXmlDoc, "//xhtml:p[1]/xhtml:br", 1);
+    assertXPath(mpXmlDoc, "//xhtml:p[1]/xhtml:span/xhtml:br", 1);
     // This was 0, line break inside span was not handled.
-    assertXPath(mpXmlDoc, "//xhtml:p[2]/xhtml:br", 1);
+    assertXPath(mpXmlDoc, "//xhtml:p[2]/xhtml:span/xhtml:br", 1);
 }
 
 void EPUBExportTest::testEscape()
@@ -345,6 +347,21 @@ void EPUBExportTest::testEscape()
     assertXPathContent(mpXmlDoc, "//xhtml:p[1]/xhtml:span[3]", "\t");
 }
 
+void EPUBExportTest::testParaCharProps()
+{
+    createDoc("para-char-props.fodt", {});
+
+    mpXmlDoc = parseExport("OEBPS/sections/section0001.xhtml");
+    // Check formatting of the middle span.
+    OString aMiddle = getXPath(mpXmlDoc, "//xhtml:p/xhtml:span[2]", "class").toUtf8();
+    std::map< OString, std::vector<OString> > aCssDoc;
+    parseCssExport("OEBPS/styles/stylesheet.css", aCssDoc);
+    assertCss(aCssDoc, aMiddle, "  font-style: italic;");
+    // Direct para formatting was lost, only direct char formatting was
+    // written, so this failed.
+    assertCss(aCssDoc, aMiddle, "  font-weight: bold;");
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(EPUBExportTest);
 
 }
diff --git a/writerperfect/qa/unit/data/writer/epubexport/para-char-props.fodt b/writerperfect/qa/unit/data/writer/epubexport/para-char-props.fodt
new file mode 100644
index 000000000000..67fe02db2bc5
--- /dev/null
+++ b/writerperfect/qa/unit/data/writer/epubexport/para-char-props.fodt
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.text">
+  <office:automatic-styles>
+    <style:style style:name="P1" style:family="paragraph">
+      <style:text-properties fo:font-weight="bold" />
+    </style:style>
+    <style:style style:name="T1" style:family="text">
+      <style:text-properties fo:font-style="italic"/>
+    </style:style>
+  </office:automatic-styles>
+  <office:body>
+    <office:text>
+      <text:p text:style-name="P1">a<text:span text:style-name="T1">b</text:span>c</text:p>
+    </office:text>
+  </office:body>
+</office:document>
diff --git a/writerperfect/source/writer/exp/txtparai.cxx b/writerperfect/source/writer/exp/txtparai.cxx
index e660a34b1e30..8e19475b65fe 100644
--- a/writerperfect/source/writer/exp/txtparai.cxx
+++ b/writerperfect/source/writer/exp/txtparai.cxx
@@ -74,7 +74,7 @@ namespace exp
 class XMLSpanContext : public XMLImportContext
 {
 public:
-    XMLSpanContext(XMLImport &rImport, const librevenge::RVNGPropertyList *pPropertyList);
+    XMLSpanContext(XMLImport &rImport, const librevenge::RVNGPropertyList &rPropertyList);
 
     XMLImportContext *CreateChildContext(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &xAttribs) override;
 
@@ -85,14 +85,11 @@ private:
     librevenge::RVNGPropertyList m_aPropertyList;
 };
 
-XMLSpanContext::XMLSpanContext(XMLImport &rImport, const librevenge::RVNGPropertyList *pPropertyList)
+XMLSpanContext::XMLSpanContext(XMLImport &rImport, const librevenge::RVNGPropertyList &rPropertyList)
     : XMLImportContext(rImport)
 {
-    if (!pPropertyList)
-        return;
-
-    // Inherit properties from parent span.
-    librevenge::RVNGPropertyList::Iter itProp(*pPropertyList);
+    // Inherit properties from parent.
+    librevenge::RVNGPropertyList::Iter itProp(rPropertyList);
     for (itProp.rewind(); itProp.next();)
         m_aPropertyList.insert(itProp.key(), itProp()->clone());
 }
@@ -101,9 +98,7 @@ XMLImportContext *XMLSpanContext::CreateChildContext(const OUString &rName, cons
 {
     if (rName == "draw:frame")
         return new XMLTextFrameContext(mrImport);
-    if (rName == "text:span")
-        return new XMLSpanContext(mrImport, &m_aPropertyList);
-    return writerperfect::exp::CreateChildContext(mrImport, rName);
+    return CreateParagraphOrSpanChildContext(mrImport, rName, m_aPropertyList);
 }
 
 void XMLSpanContext::startElement(const OUString &/*rName*/, const css::uno::Reference<css::xml::sax::XAttributeList> &xAttribs)
@@ -133,63 +128,84 @@ void XMLSpanContext::characters(const OUString &rChars)
     mrImport.GetGenerator().closeSpan();
 }
 
+/// Base class for contexts that represent a single character only.
+class XMLCharContext : public XMLImportContext
+{
+public:
+    XMLCharContext(XMLImport &rImport, const librevenge::RVNGPropertyList &rPropertyList);
+
+protected:
+    librevenge::RVNGPropertyList m_aPropertyList;
+};
+
+XMLCharContext::XMLCharContext(XMLImport &rImport, const librevenge::RVNGPropertyList &rPropertyList)
+    : XMLImportContext(rImport)
+{
+    // Inherit properties from parent.
+    librevenge::RVNGPropertyList::Iter itProp(rPropertyList);
+    for (itProp.rewind(); itProp.next();)
+        m_aPropertyList.insert(itProp.key(), itProp()->clone());
+}
+
 /// Handler for <text:line-break>.
-class XMLLineBreakContext : public XMLImportContext
+class XMLLineBreakContext : public XMLCharContext
 {
 public:
-    XMLLineBreakContext(XMLImport &rImport);
+    XMLLineBreakContext(XMLImport &rImport, const librevenge::RVNGPropertyList &rPropertyList);
 
     void SAL_CALL startElement(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &xAttribs) override;
 };
 
-XMLLineBreakContext::XMLLineBreakContext(XMLImport &rImport)
-    : XMLImportContext(rImport)
+XMLLineBreakContext::XMLLineBreakContext(XMLImport &rImport, const librevenge::RVNGPropertyList &rPropertyList)
+    : XMLCharContext(rImport, rPropertyList)
 {
 }
 
 void XMLLineBreakContext::startElement(const OUString &/*rName*/, const css::uno::Reference<css::xml::sax::XAttributeList> &/*xAttribs*/)
 {
+    mrImport.GetGenerator().openSpan(m_aPropertyList);
     mrImport.GetGenerator().insertLineBreak();
+    mrImport.GetGenerator().closeSpan();
 }
 
 /// Handler for <text:s>.
-class XMLSpaceContext : public XMLImportContext
+class XMLSpaceContext : public XMLCharContext
 {
 public:
-    XMLSpaceContext(XMLImport &rImport);
+    XMLSpaceContext(XMLImport &rImport, const librevenge::RVNGPropertyList &rPropertyList);
 
     void SAL_CALL startElement(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &xAttribs) override;
 };
 
-XMLSpaceContext::XMLSpaceContext(XMLImport &rImport)
-    : XMLImportContext(rImport)
+XMLSpaceContext::XMLSpaceContext(XMLImport &rImport, const librevenge::RVNGPropertyList &rPropertyList)
+    : XMLCharContext(rImport, rPropertyList)
 {
 }
 
 void XMLSpaceContext::startElement(const OUString &/*rName*/, const css::uno::Reference<css::xml::sax::XAttributeList> &/*xAttribs*/)
 {
-    mrImport.GetGenerator().openSpan(librevenge::RVNGPropertyList());
+    mrImport.GetGenerator().openSpan(m_aPropertyList);
     mrImport.GetGenerator().insertSpace();
     mrImport.GetGenerator().closeSpan();
 }
 
 /// Handler for <text:tab>.
-class XMLTabContext : public XMLImportContext
+class XMLTabContext : public XMLCharContext
 {
 public:
-    XMLTabContext(XMLImport &rImport);
+    XMLTabContext(XMLImport &rImport, const librevenge::RVNGPropertyList &rPropertyList);
 
     void SAL_CALL startElement(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &xAttribs) override;
 };
 
-XMLTabContext::XMLTabContext(XMLImport &rImport)
-    : XMLImportContext(rImport)
+XMLTabContext::XMLTabContext(XMLImport &rImport, const librevenge::RVNGPropertyList &rPropertyList)
+    : XMLCharContext(rImport, rPropertyList)
 {
 }
 
 void XMLTabContext::startElement(const OUString &/*rName*/, const css::uno::Reference<css::xml::sax::XAttributeList> &/*xAttribs*/)
 {
-    mrImport.GetGenerator().openSpan(librevenge::RVNGPropertyList());
+    mrImport.GetGenerator().openSpan(m_aPropertyList);
     mrImport.GetGenerator().insertTab();
     mrImport.GetGenerator().closeSpan();
 }
@@ -245,11 +261,9 @@ XMLParaContext::XMLParaContext(XMLImport &rImport)
 
 XMLImportContext *XMLParaContext::CreateChildContext(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &/*xAttribs*/)
 {
-    if (rName == "text:span")
-        return new XMLSpanContext(mrImport, nullptr);
     if (rName == "text:a")
         return new XMLHyperlinkContext(mrImport);
-    return writerperfect::exp::CreateChildContext(mrImport, rName);
+    return CreateParagraphOrSpanChildContext(mrImport, rName, m_aTextPropertyList);
 }
 
 void XMLParaContext::startElement(const OUString &/*rName*/, const css::uno::Reference<css::xml::sax::XAttributeList> &xAttribs)
@@ -263,6 +277,7 @@ void XMLParaContext::startElement(const OUString &/*rName*/, const css::uno::Ref
         {
             m_aStyleName = rAttributeValue;
             FillStyles(m_aStyleName, mrImport.GetAutomaticParagraphStyles(), mrImport.GetParagraphStyles(), aPropertyList);
+            FillStyles(m_aStyleName, mrImport.GetAutomaticTextStyles(), mrImport.GetTextStyles(), m_aTextPropertyList);
         }
         else
         {
@@ -293,14 +308,16 @@ void XMLParaContext::characters(const OUString &rChars)
     mrImport.GetGenerator().closeSpan();
 }
 
-XMLImportContext *CreateChildContext(XMLImport &rImport, const OUString &rName)
+XMLImportContext *CreateParagraphOrSpanChildContext(XMLImport &rImport, const OUString &rName, const librevenge::RVNGPropertyList &rTextPropertyList)
 {
+    if (rName == "text:span")
+        return new XMLSpanContext(rImport, rTextPropertyList);
     if (rName == "text:line-break")
-        return new XMLLineBreakContext(rImport);
+        return new XMLLineBreakContext(rImport, rTextPropertyList);
     if (rName == "text:s")
-        return new XMLSpaceContext(rImport);
+        return new XMLSpaceContext(rImport, rTextPropertyList);
     if (rName == "text:tab")
-        return new XMLTabContext(rImport);
+        return new XMLTabContext(rImport, rTextPropertyList);
     return nullptr;
 }
 
diff --git a/writerperfect/source/writer/exp/txtparai.hxx b/writerperfect/source/writer/exp/txtparai.hxx
index 52543ffeadde..a427d2602516 100644
--- a/writerperfect/source/writer/exp/txtparai.hxx
+++ b/writerperfect/source/writer/exp/txtparai.hxx
@@ -31,10 +31,12 @@ public:
 
 private:
     OUString m_aStyleName;
+    /// List of properties spans should inherit from this paragraph.
+    librevenge::RVNGPropertyList m_aTextPropertyList;
 };
 
 /// Shared child context factory for paragraph and span contexts.
-XMLImportContext *CreateChildContext(XMLImport &rImport, const OUString &rName);
+XMLImportContext *CreateParagraphOrSpanChildContext(XMLImport &rImport, const OUString &rName, const librevenge::RVNGPropertyList &rTextPropertyList);
 
 } // namespace exp
 } // namespace writerperfect


More information about the Libreoffice-commits mailing list