diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2017-08-29 17:56:28 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2017-08-30 10:02:32 +0200 |
commit | dfdc113bbd852e8f4b4863db457e2938aaad0c64 (patch) | |
tree | b6b0b5304a7fe1a345b69951448f46d9fec013fc /writerperfect | |
parent | 0be2ac10cb4baf14e8ba9f30a10c5b5ad3a7197d (diff) |
EPUB export: support char props on text outside a span
The librevenge model is simpler: text is always in a span, and paragraph
(automatic) styles don't contain char props, either. So handle this
complexity on our side.
Change-Id: I017222539d8981d2bbbc632258662444bf3a79c8
Reviewed-on: https://gerrit.libreoffice.org/41705
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Tested-by: Jenkins <ci@libreoffice.org>
Diffstat (limited to 'writerperfect')
-rw-r--r-- | writerperfect/qa/unit/EPUBExportTest.cxx | 12 | ||||
-rw-r--r-- | writerperfect/qa/unit/data/writer/epubexport/para-autostyle-char-props.fodt | 21 | ||||
-rw-r--r-- | writerperfect/source/writer/exp/txtparai.cxx | 33 | ||||
-rw-r--r-- | writerperfect/source/writer/exp/txtparai.hxx | 3 | ||||
-rw-r--r-- | writerperfect/source/writer/exp/txtstyli.cxx | 23 | ||||
-rw-r--r-- | writerperfect/source/writer/exp/txtstyli.hxx | 7 | ||||
-rw-r--r-- | writerperfect/source/writer/exp/xmlimp.cxx | 9 | ||||
-rw-r--r-- | writerperfect/source/writer/exp/xmlimp.hxx | 6 |
8 files changed, 93 insertions, 21 deletions
diff --git a/writerperfect/qa/unit/EPUBExportTest.cxx b/writerperfect/qa/unit/EPUBExportTest.cxx index 857f6ec85df3..fef1cf19770c 100644 --- a/writerperfect/qa/unit/EPUBExportTest.cxx +++ b/writerperfect/qa/unit/EPUBExportTest.cxx @@ -52,6 +52,7 @@ public: void testEPUB2(); void testPageBreakSplit(); void testSpanAutostyle(); + void testParaAutostyleCharProps(); CPPUNIT_TEST_SUITE(EPUBExportTest); CPPUNIT_TEST(testOutlineLevel); @@ -59,6 +60,7 @@ public: CPPUNIT_TEST(testEPUB2); CPPUNIT_TEST(testPageBreakSplit); CPPUNIT_TEST(testSpanAutostyle); + CPPUNIT_TEST(testParaAutostyleCharProps); CPPUNIT_TEST_SUITE_END(); }; @@ -190,6 +192,16 @@ void EPUBExportTest::testSpanAutostyle() assertXPath(mpXmlDoc, "//xhtml:p/xhtml:span[3]", "class", "span2"); } +void EPUBExportTest::testParaAutostyleCharProps() +{ + createDoc("para-autostyle-char-props.fodt", {}); + + mpXmlDoc = parseExport("OEBPS/sections/section0001.xhtml"); + // This failed, para-level char props were not exported. + assertXPath(mpXmlDoc, "//xhtml:p[1]/xhtml:span", "class", "span0"); + assertXPath(mpXmlDoc, "//xhtml:p[2]/xhtml:span", "class", "span1"); +} + CPPUNIT_TEST_SUITE_REGISTRATION(EPUBExportTest); } diff --git a/writerperfect/qa/unit/data/writer/epubexport/para-autostyle-char-props.fodt b/writerperfect/qa/unit/data/writer/epubexport/para-autostyle-char-props.fodt new file mode 100644 index 000000000000..ceb556940b8f --- /dev/null +++ b/writerperfect/qa/unit/data/writer/epubexport/para-autostyle-char-props.fodt @@ -0,0 +1,21 @@ +<?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" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.text"> + <office:font-face-decls> + <style:font-face style:name="Liberation Serif" svg:font-family="'Liberation Serif'" style:font-family-generic="roman" style:font-pitch="variable"/> + <style:font-face style:name="Liberation Sans" svg:font-family="'Liberation Sans'" style:font-family-generic="swiss" style:font-pitch="variable"/> + </office:font-face-decls> + <office:automatic-styles> + <style:style style:name="P1" style:family="paragraph"> + <style:text-properties style:font-name="Liberation Serif"/> + </style:style> + <style:style style:name="P2" style:family="paragraph"> + <style:text-properties style:font-name="Liberation Sans"/> + </style:style> + </office:automatic-styles> + <office:body> + <office:text> + <text:p text:style-name="P1">This is serif.</text:p> + <text:p text:style-name="P2">This is sans.</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 50ff36352ad5..293fb10eb3d3 100644 --- a/writerperfect/source/writer/exp/txtparai.cxx +++ b/writerperfect/source/writer/exp/txtparai.cxx @@ -53,9 +53,9 @@ void XMLSpanContext::startElement(const OUString &/*rName*/, const css::uno::Ref const OUString &rAttributeValue = xAttribs->getValueByIndex(i); if (rAttributeName == "text:style-name") { - // Reference to an automatic style, try to look it up. - auto itStyle = mrImport.GetAutomaticStyles().find(rAttributeValue); - if (itStyle == mrImport.GetAutomaticStyles().end()) + // Reference to an automatic text style, try to look it up. + auto itStyle = mrImport.GetAutomaticTextStyles().find(rAttributeValue); + if (itStyle == mrImport.GetAutomaticTextStyles().end()) continue; // Apply properties directly, librevenge has no notion of automatic styles. @@ -152,15 +152,17 @@ void XMLParaContext::startElement(const OUString &/*rName*/, const css::uno::Ref const OUString &rAttributeValue = xAttribs->getValueByIndex(i); if (rAttributeName == "text:style-name") { + m_aStyleName = rAttributeValue; + // Reference to an automatic style, try to look it up. - auto itStyle = mrImport.GetAutomaticStyles().find(rAttributeValue); - if (itStyle == mrImport.GetAutomaticStyles().end()) + auto itStyle = mrImport.GetAutomaticParagraphStyles().find(m_aStyleName); + if (itStyle == mrImport.GetAutomaticParagraphStyles().end()) continue; - // Apply properties directly, librevenge has no notion of automatic styles. + // Found an automatic paragraph style. librevenge::RVNGPropertyList::Iter itProp(itStyle->second); for (itProp.rewind(); itProp.next();) - aPropertyList.insert(itProp.key(), itProp()); + aPropertyList.insert(itProp.key(), itProp()->clone()); } else { @@ -180,8 +182,25 @@ void XMLParaContext::endElement(const OUString &/*rName*/) void XMLParaContext::characters(const OUString &rChars) { + librevenge::RVNGPropertyList aPropertyList; + if (!m_aStyleName.isEmpty()) + { + // Reference to an automatic style, try to look it up. + auto itStyle = mrImport.GetAutomaticTextStyles().find(m_aStyleName); + if (itStyle != mrImport.GetAutomaticTextStyles().end()) + { + // Found an automatic text style. + librevenge::RVNGPropertyList::Iter itProp(itStyle->second); + for (itProp.rewind(); itProp.next();) + aPropertyList.insert(itProp.key(), itProp()->clone()); + } + } + mrImport.GetGenerator().openSpan(aPropertyList); + OString sCharU8 = OUStringToOString(rChars, RTL_TEXTENCODING_UTF8); mrImport.GetGenerator().insertText(librevenge::RVNGString(sCharU8.getStr())); + + mrImport.GetGenerator().closeSpan(); } } // namespace exp diff --git a/writerperfect/source/writer/exp/txtparai.hxx b/writerperfect/source/writer/exp/txtparai.hxx index 6c9f23b6cf37..61c3fc5bfc73 100644 --- a/writerperfect/source/writer/exp/txtparai.hxx +++ b/writerperfect/source/writer/exp/txtparai.hxx @@ -28,6 +28,9 @@ public: void SAL_CALL startElement(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &xAttribs) override; void SAL_CALL endElement(const OUString &rName) override; void SAL_CALL characters(const OUString &rChars) override; + +private: + OUString m_aStyleName; }; } // namespace exp diff --git a/writerperfect/source/writer/exp/txtstyli.cxx b/writerperfect/source/writer/exp/txtstyli.cxx index 2d39816da4ef..49c2ccd45aeb 100644 --- a/writerperfect/source/writer/exp/txtstyli.cxx +++ b/writerperfect/source/writer/exp/txtstyli.cxx @@ -42,7 +42,7 @@ void XMLParagraphPropertiesContext::startElement(const OUString &/*rName*/, cons { OString sName = OUStringToOString(xAttribs->getNameByIndex(i), RTL_TEXTENCODING_UTF8); OString sValue = OUStringToOString(xAttribs->getValueByIndex(i), RTL_TEXTENCODING_UTF8); - mrStyle.GetPropertyList().insert(sName.getStr(), sValue.getStr()); + mrStyle.GetParagraphPropertyList().insert(sName.getStr(), sValue.getStr()); } } @@ -70,7 +70,7 @@ void XMLTextPropertiesContext::startElement(const OUString &/*rName*/, const css { OString sName = OUStringToOString(xAttribs->getNameByIndex(i), RTL_TEXTENCODING_UTF8); OString sValue = OUStringToOString(xAttribs->getValueByIndex(i), RTL_TEXTENCODING_UTF8); - mrStyle.GetPropertyList().insert(sName.getStr(), sValue.getStr()); + mrStyle.GetTextPropertyList().insert(sName.getStr(), sValue.getStr()); } } @@ -94,10 +94,9 @@ void XMLStyleContext::startElement(const OUString &/*rName*/, const css::uno::Re { const OUString &rAttributeName = xAttribs->getNameByIndex(i); if (rAttributeName == "style:name") - { m_aName = xAttribs->getValueByIndex(i); - break; - } + else if (rAttributeName == "style:family") + m_aFamily = xAttribs->getValueByIndex(i); } } @@ -106,12 +105,20 @@ void XMLStyleContext::endElement(const OUString &/*rName*/) if (m_aName.isEmpty()) return; - mrImport.GetAutomaticStyles()[m_aName] = m_aPropertyList; + if (m_aFamily == "text" || m_aFamily == "paragraph") + mrImport.GetAutomaticTextStyles()[m_aName] = m_aTextPropertyList; + if (m_aFamily == "paragraph") + mrImport.GetAutomaticParagraphStyles()[m_aName] = m_aParagraphPropertyList; } -librevenge::RVNGPropertyList &XMLStyleContext::GetPropertyList() +librevenge::RVNGPropertyList &XMLStyleContext::GetTextPropertyList() { - return m_aPropertyList; + return m_aTextPropertyList; +} + +librevenge::RVNGPropertyList &XMLStyleContext::GetParagraphPropertyList() +{ + return m_aParagraphPropertyList; } } // namespace exp diff --git a/writerperfect/source/writer/exp/txtstyli.hxx b/writerperfect/source/writer/exp/txtstyli.hxx index 89d3483b7ba7..af9d1bbd44f4 100644 --- a/writerperfect/source/writer/exp/txtstyli.hxx +++ b/writerperfect/source/writer/exp/txtstyli.hxx @@ -29,11 +29,14 @@ public: void SAL_CALL startElement(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &xAttribs) override; void SAL_CALL endElement(const OUString &rName) override; - librevenge::RVNGPropertyList &GetPropertyList(); + librevenge::RVNGPropertyList &GetTextPropertyList(); + librevenge::RVNGPropertyList &GetParagraphPropertyList(); private: OUString m_aName; - librevenge::RVNGPropertyList m_aPropertyList; + OUString m_aFamily; + librevenge::RVNGPropertyList m_aTextPropertyList; + librevenge::RVNGPropertyList m_aParagraphPropertyList; }; } // namespace exp diff --git a/writerperfect/source/writer/exp/xmlimp.cxx b/writerperfect/source/writer/exp/xmlimp.cxx index 2fa46cdad98f..5c95efbd0109 100644 --- a/writerperfect/source/writer/exp/xmlimp.cxx +++ b/writerperfect/source/writer/exp/xmlimp.cxx @@ -84,9 +84,14 @@ librevenge::RVNGTextInterface &XMLImport::GetGenerator() const return mrGenerator; } -std::map<OUString, librevenge::RVNGPropertyList> &XMLImport::GetAutomaticStyles() +std::map<OUString, librevenge::RVNGPropertyList> &XMLImport::GetAutomaticTextStyles() { - return maAutomaticStyles; + return maAutomaticTextStyles; +} + +std::map<OUString, librevenge::RVNGPropertyList> &XMLImport::GetAutomaticParagraphStyles() +{ + return maAutomaticParagraphStyles; } void XMLImport::startDocument() diff --git a/writerperfect/source/writer/exp/xmlimp.hxx b/writerperfect/source/writer/exp/xmlimp.hxx index 5ba8d37c73aa..ed6350348038 100644 --- a/writerperfect/source/writer/exp/xmlimp.hxx +++ b/writerperfect/source/writer/exp/xmlimp.hxx @@ -35,7 +35,8 @@ class XMLImport : public cppu::WeakImplHelper { librevenge::RVNGTextInterface &mrGenerator; std::stack< rtl::Reference<XMLImportContext> > maContexts; - std::map<OUString, librevenge::RVNGPropertyList> maAutomaticStyles; + std::map<OUString, librevenge::RVNGPropertyList> maAutomaticTextStyles; + std::map<OUString, librevenge::RVNGPropertyList> maAutomaticParagraphStyles; public: XMLImport(librevenge::RVNGTextInterface &rGenerator); @@ -43,7 +44,8 @@ public: XMLImportContext *CreateContext(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &xAttribs); librevenge::RVNGTextInterface &GetGenerator() const; - std::map<OUString, librevenge::RVNGPropertyList> &GetAutomaticStyles(); + std::map<OUString, librevenge::RVNGPropertyList> &GetAutomaticTextStyles(); + std::map<OUString, librevenge::RVNGPropertyList> &GetAutomaticParagraphStyles(); // XDocumentHandler void SAL_CALL startDocument() override; |