EPUB export: handle paragraph properties from paragraph styles
This adds support for inheriting paragraph properties from named
paragraph styles.
Change-Id: I3cb787f6704329a5e0d11d3cd0266254749ac5ae
Reviewed-on: https://gerrit.libreoffice.org/41938
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Tested-by: Jenkins <ci@libreoffice.org>
diff --git a/writerperfect/qa/unit/EPUBExportTest.cxx b/writerperfect/qa/unit/EPUBExportTest.cxx
index 61a6da2..5163c72 100644
--- a/writerperfect/qa/unit/EPUBExportTest.cxx
+++ b/writerperfect/qa/unit/EPUBExportTest.cxx
@@ -54,6 +54,7 @@ public:
void testSpanAutostyle();
void testParaAutostyleCharProps();
void testMeta();
void testParaNamedstyle();
CPPUNIT_TEST_SUITE(EPUBExportTest);
CPPUNIT_TEST(testOutlineLevel);
@@ -63,6 +64,7 @@ public:
CPPUNIT_TEST(testSpanAutostyle);
CPPUNIT_TEST(testParaAutostyleCharProps);
CPPUNIT_TEST(testMeta);
CPPUNIT_TEST(testParaNamedstyle);
CPPUNIT_TEST_SUITE_END();
};
@@ -215,6 +217,16 @@ void EPUBExportTest::testMeta()
assertXPathContent(mpXmlDoc, "/opf:package/opf:metadata/dc:title", "Title");
}
void EPUBExportTest::testParaNamedstyle()
{
createDoc("para-namedstyle.fodt", {});
mpXmlDoc = parseExport("OEBPS/sections/section0001.xhtml");
assertXPath(mpXmlDoc, "//xhtml:p[1]", "class", "para0");
// This failed, paragraph properties from style were not exported.
assertXPath(mpXmlDoc, "//xhtml:p[2]", "class", "para1");
}
CPPUNIT_TEST_SUITE_REGISTRATION(EPUBExportTest);
}
diff --git a/writerperfect/qa/unit/data/writer/epubexport/para-namedstyle.fodt b/writerperfect/qa/unit/data/writer/epubexport/para-namedstyle.fodt
new file mode 100644
index 0000000..887a5c1
--- /dev/null
+++ b/writerperfect/qa/unit/data/writer/epubexport/para-namedstyle.fodt
@@ -0,0 +1,18 @@
<?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 Sans" svg:font-family="'Liberation Sans'" style:font-family-generic="swiss" style:font-pitch="variable"/>
</office:font-face-decls>
<office:styles>
<style:style style:name="Heading" style:family="paragraph" style:class="text">
<style:paragraph-properties fo:margin-top="0.423cm" fo:margin-bottom="0.212cm" fo:keep-with-next="always"/>
<style:text-properties style:font-name="Liberation Sans" fo:font-family="'Liberation Sans'" style:font-family-generic="swiss" style:font-pitch="variable" fo:font-size="14pt"/>
</style:style>
</office:styles>
<office:body>
<office:text>
<text:h text:style-name="Heading" text:outline-level="1">Heading</text:h>
<text:p>Text Body</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 293fb10..b812549 100644
--- a/writerperfect/source/writer/exp/txtparai.cxx
+++ b/writerperfect/source/writer/exp/txtparai.cxx
@@ -156,13 +156,23 @@ void XMLParaContext::startElement(const OUString &/*rName*/, const css::uno::Ref
// Reference to an automatic style, try to look it up.
auto itStyle = mrImport.GetAutomaticParagraphStyles().find(m_aStyleName);
if (itStyle == mrImport.GetAutomaticParagraphStyles().end())
if (itStyle != mrImport.GetAutomaticParagraphStyles().end())
{
// Found an automatic paragraph style.
librevenge::RVNGPropertyList::Iter itProp(itStyle->second);
for (itProp.rewind(); itProp.next();)
aPropertyList.insert(itProp.key(), itProp()->clone());
continue;
}
// Found an automatic paragraph style.
librevenge::RVNGPropertyList::Iter itProp(itStyle->second);
for (itProp.rewind(); itProp.next();)
aPropertyList.insert(itProp.key(), itProp()->clone());
itStyle = mrImport.GetParagraphStyles().find(m_aStyleName);
if (itStyle != mrImport.GetParagraphStyles().end())
{
// Found a paragraph style.
librevenge::RVNGPropertyList::Iter itProp(itStyle->second);
for (itProp.rewind(); itProp.next();)
aPropertyList.insert(itProp.key(), itProp()->clone());
}
}
else
{
diff --git a/writerperfect/source/writer/exp/txtstyli.cxx b/writerperfect/source/writer/exp/txtstyli.cxx
index 49c2ccd..a3e8395 100644
--- a/writerperfect/source/writer/exp/txtstyli.cxx
+++ b/writerperfect/source/writer/exp/txtstyli.cxx
@@ -9,6 +9,7 @@
#include "txtstyli.hxx"
#include "xmlfmt.hxx"
#include "xmlimp.hxx"
using namespace com::sun::star;
@@ -74,8 +75,9 @@ void XMLTextPropertiesContext::startElement(const OUString &/*rName*/, const css
}
}
XMLStyleContext::XMLStyleContext(XMLImport &rImport)
: XMLImportContext(rImport)
XMLStyleContext::XMLStyleContext(XMLImport &rImport, XMLStylesContext &rStyles)
: XMLImportContext(rImport),
m_rStyles(rStyles)
{
}
@@ -106,9 +108,9 @@ void XMLStyleContext::endElement(const OUString &/*rName*/)
return;
if (m_aFamily == "text" || m_aFamily == "paragraph")
mrImport.GetAutomaticTextStyles()[m_aName] = m_aTextPropertyList;
m_rStyles.GetCurrentTextStyles()[m_aName] = m_aTextPropertyList;
if (m_aFamily == "paragraph")
mrImport.GetAutomaticParagraphStyles()[m_aName] = m_aParagraphPropertyList;
m_rStyles.GetCurrentParagraphStyles()[m_aName] = m_aParagraphPropertyList;
}
librevenge::RVNGPropertyList &XMLStyleContext::GetTextPropertyList()
diff --git a/writerperfect/source/writer/exp/txtstyli.hxx b/writerperfect/source/writer/exp/txtstyli.hxx
index af9d1bb..83ffd78 100644
--- a/writerperfect/source/writer/exp/txtstyli.hxx
+++ b/writerperfect/source/writer/exp/txtstyli.hxx
@@ -19,11 +19,13 @@ namespace writerperfect
namespace exp
{
class XMLStylesContext;
/// Handler for <style:style>.
class XMLStyleContext : public XMLImportContext
{
public:
XMLStyleContext(XMLImport &rImport);
XMLStyleContext(XMLImport &rImport, XMLStylesContext &rStyles);
XMLImportContext *CreateChildContext(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &xAttribs) override;
void SAL_CALL startElement(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &xAttribs) override;
@@ -37,6 +39,7 @@ private:
OUString m_aFamily;
librevenge::RVNGPropertyList m_aTextPropertyList;
librevenge::RVNGPropertyList m_aParagraphPropertyList;
XMLStylesContext &m_rStyles;
};
} // namespace exp
diff --git a/writerperfect/source/writer/exp/xmlfmt.cxx b/writerperfect/source/writer/exp/xmlfmt.cxx
index 64fe313..b331728 100644
--- a/writerperfect/source/writer/exp/xmlfmt.cxx
+++ b/writerperfect/source/writer/exp/xmlfmt.cxx
@@ -19,18 +19,30 @@ namespace writerperfect
namespace exp
{
XMLAutomaticStylesContext::XMLAutomaticStylesContext(XMLImport &rImport)
: XMLImportContext(rImport)
XMLStylesContext::XMLStylesContext(XMLImport &rImport, std::map<OUString, librevenge::RVNGPropertyList> &rParagraphStyles, std::map<OUString, librevenge::RVNGPropertyList> &rTextStyles)
: XMLImportContext(rImport),
m_rParagraphStyles(rParagraphStyles),
m_rTextStyles(rTextStyles)
{
}
XMLImportContext *XMLAutomaticStylesContext::CreateChildContext(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &/*xAttribs*/)
XMLImportContext *XMLStylesContext::CreateChildContext(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &/*xAttribs*/)
{
if (rName == "style:style")
return new XMLStyleContext(mrImport);
return new XMLStyleContext(mrImport, *this);
return nullptr;
}
std::map<OUString, librevenge::RVNGPropertyList> &XMLStylesContext::GetCurrentParagraphStyles()
{
return m_rParagraphStyles;
}
std::map<OUString, librevenge::RVNGPropertyList> &XMLStylesContext::GetCurrentTextStyles()
{
return m_rTextStyles;
}
} // namespace exp
} // namespace writerperfect
diff --git a/writerperfect/source/writer/exp/xmlfmt.hxx b/writerperfect/source/writer/exp/xmlfmt.hxx
index 1ace95b..394be55 100644
--- a/writerperfect/source/writer/exp/xmlfmt.hxx
+++ b/writerperfect/source/writer/exp/xmlfmt.hxx
@@ -10,6 +10,8 @@
#ifndef INCLUDED_WRITERPERFECT_SOURCE_WRITER_EXP_XMLFMT_HXX
#define INCLUDED_WRITERPERFECT_SOURCE_WRITER_EXP_XMLFMT_HXX
#include <map>
#include <librevenge/librevenge.h>
#include "xmlictxt.hxx"
@@ -19,13 +21,19 @@ namespace writerperfect
namespace exp
{
/// Handler for <office:automatic-styles>.
class XMLAutomaticStylesContext : public XMLImportContext
/// Handler for <office:automatic-styles>/<office:styles>.
class XMLStylesContext : public XMLImportContext
{
public:
XMLAutomaticStylesContext(XMLImport &rImport);
XMLStylesContext(XMLImport &rImport, std::map<OUString, librevenge::RVNGPropertyList> &rParagraphStyles, std::map<OUString, librevenge::RVNGPropertyList> &rTextStyles);
XMLImportContext *CreateChildContext(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &xAttribs) override;
std::map<OUString, librevenge::RVNGPropertyList> &GetCurrentParagraphStyles();
std::map<OUString, librevenge::RVNGPropertyList> &GetCurrentTextStyles();
private:
std::map<OUString, librevenge::RVNGPropertyList> &m_rParagraphStyles;
std::map<OUString, librevenge::RVNGPropertyList> &m_rTextStyles;
};
} // namespace exp
diff --git a/writerperfect/source/writer/exp/xmlimp.cxx b/writerperfect/source/writer/exp/xmlimp.cxx
index 5c95efb..2370399e 100644
--- a/writerperfect/source/writer/exp/xmlimp.cxx
+++ b/writerperfect/source/writer/exp/xmlimp.cxx
@@ -63,7 +63,9 @@ XMLImportContext *XMLOfficeDocContext::CreateChildContext(const OUString &rName,
else if (rName == "office:meta")
return new XMLMetaDocumentContext(mrImport);
else if (rName == "office:automatic-styles")
return new XMLAutomaticStylesContext(mrImport);
return new XMLStylesContext(mrImport, mrImport.GetAutomaticParagraphStyles(), mrImport.GetAutomaticTextStyles());
else if (rName == "office:styles")
return new XMLStylesContext(mrImport, mrImport.GetParagraphStyles(), mrImport.GetTextStyles());
return nullptr;
}
@@ -94,6 +96,16 @@ std::map<OUString, librevenge::RVNGPropertyList> &XMLImport::GetAutomaticParagra
return maAutomaticParagraphStyles;
}
std::map<OUString, librevenge::RVNGPropertyList> &XMLImport::GetTextStyles()
{
return maTextStyles;
}
std::map<OUString, librevenge::RVNGPropertyList> &XMLImport::GetParagraphStyles()
{
return maParagraphStyles;
}
void XMLImport::startDocument()
{
mrGenerator.startDocument(librevenge::RVNGPropertyList());
diff --git a/writerperfect/source/writer/exp/xmlimp.hxx b/writerperfect/source/writer/exp/xmlimp.hxx
index ed63503..128a88c 100644
--- a/writerperfect/source/writer/exp/xmlimp.hxx
+++ b/writerperfect/source/writer/exp/xmlimp.hxx
@@ -36,7 +36,9 @@ class XMLImport : public cppu::WeakImplHelper
librevenge::RVNGTextInterface &mrGenerator;
std::stack< rtl::Reference<XMLImportContext> > maContexts;
std::map<OUString, librevenge::RVNGPropertyList> maAutomaticTextStyles;
std::map<OUString, librevenge::RVNGPropertyList> maTextStyles;
std::map<OUString, librevenge::RVNGPropertyList> maAutomaticParagraphStyles;
std::map<OUString, librevenge::RVNGPropertyList> maParagraphStyles;
public:
XMLImport(librevenge::RVNGTextInterface &rGenerator);
@@ -46,6 +48,8 @@ public:
librevenge::RVNGTextInterface &GetGenerator() const;
std::map<OUString, librevenge::RVNGPropertyList> &GetAutomaticTextStyles();
std::map<OUString, librevenge::RVNGPropertyList> &GetAutomaticParagraphStyles();
std::map<OUString, librevenge::RVNGPropertyList> &GetTextStyles();
std::map<OUString, librevenge::RVNGPropertyList> &GetParagraphStyles();
// XDocumentHandler
void SAL_CALL startDocument() override;