summaryrefslogtreecommitdiff
path: root/writerperfect
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2017-09-08 15:55:03 +0200
committerMiklos Vajna <vmiklos@collabora.co.uk>2017-09-08 17:56:22 +0200
commit687fdc5750ac756f157c663197b998eb471612ef (patch)
tree23b0ecc6c37a540400ec28f9bcb71f9c1e3e4574 /writerperfect
parent8d1c4032ed284e656300801b62c982e212315a07 (diff)
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@collabora.co.uk> Tested-by: Jenkins <ci@libreoffice.org>
Diffstat (limited to 'writerperfect')
-rw-r--r--writerperfect/qa/unit/EPUBExportTest.cxx21
-rw-r--r--writerperfect/qa/unit/data/writer/epubexport/para-char-props.fodt16
-rw-r--r--writerperfect/source/writer/exp/txtparai.cxx79
-rw-r--r--writerperfect/source/writer/exp/txtparai.hxx4
4 files changed, 86 insertions, 34 deletions
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