diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2017-08-25 17:46:20 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2017-08-25 21:36:03 +0200 |
commit | 1584d5215cd38be1f7cf14efbfac2e08ef4a0705 (patch) | |
tree | b98b895e0d461c50c8e6a6211e1eb8a51a6c8ec6 /writerperfect | |
parent | 64ced968cc82b552e178da033e7a3b5af6996ae1 (diff) |
EPUB export: allow custom split method
Default is split on heading, but this allows e.g. split on page break
instead.
Change-Id: Ie392fc76f91d60029c7e5f2a0adc55cb18f6157d
Reviewed-on: https://gerrit.libreoffice.org/41577
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Diffstat (limited to 'writerperfect')
4 files changed, 68 insertions, 11 deletions
diff --git a/writerperfect/CppunitTest_writerperfect_epubexport.mk b/writerperfect/CppunitTest_writerperfect_epubexport.mk index 00a49a522805..a74de9ebc7fd 100644 --- a/writerperfect/CppunitTest_writerperfect_epubexport.mk +++ b/writerperfect/CppunitTest_writerperfect_epubexport.mk @@ -28,7 +28,9 @@ $(eval $(call gb_CppunitTest_use_libraries,writerperfect_epubexport, \ )) $(eval $(call gb_CppunitTest_use_externals,writerperfect_epubexport,\ + epubgen \ libxml2 \ + revenge \ )) $(eval $(call gb_CppunitTest_use_external,writerperfect_epubexport,boost_headers)) diff --git a/writerperfect/qa/unit/EPUBExportTest.cxx b/writerperfect/qa/unit/EPUBExportTest.cxx index 859e98374cb5..f6e0d756fd25 100644 --- a/writerperfect/qa/unit/EPUBExportTest.cxx +++ b/writerperfect/qa/unit/EPUBExportTest.cxx @@ -7,6 +7,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include <libepubgen/libepubgen.h> + #include <com/sun/star/frame/Desktop.hpp> #include <com/sun/star/frame/XStorable.hpp> #include <com/sun/star/packages/zip/ZipFileAccess.hpp> @@ -34,20 +36,26 @@ class EPUBExportTest : public test::BootstrapFixture, public unotest::MacrosTest uno::Reference<uno::XComponentContext> mxComponentContext; uno::Reference<lang::XComponent> mxComponent; utl::TempFile maTempFile; + xmlDocPtr mpXmlDoc = nullptr; + uno::Reference<packages::zip::XZipFileAccess2> mxZipFile; public: void setUp() override; void tearDown() override; void registerNamespaces(xmlXPathContextPtr &pXmlXpathCtx) override; void createDoc(const OUString &rFile, const uno::Sequence<beans::PropertyValue> &rFilterData); + /// Returns an XML representation of the stream named rName in the exported package. + xmlDocPtr parseExport(const OUString &rName); void testOutlineLevel(); void testMimetype(); void testEPUB2(); + void testPageBreakSplit(); CPPUNIT_TEST_SUITE(EPUBExportTest); CPPUNIT_TEST(testOutlineLevel); CPPUNIT_TEST(testMimetype); CPPUNIT_TEST(testEPUB2); + CPPUNIT_TEST(testPageBreakSplit); CPPUNIT_TEST_SUITE_END(); }; @@ -64,6 +72,12 @@ void EPUBExportTest::tearDown() if (mxComponent.is()) mxComponent->dispose(); + if (mpXmlDoc) + { + xmlFreeDoc(mpXmlDoc); + mpXmlDoc = nullptr; + } + test::BootstrapFixture::tearDown(); } @@ -85,6 +99,14 @@ void EPUBExportTest::createDoc(const OUString &rFile, const uno::Sequence<beans: aMediaDescriptor["FilterName"] <<= OUString("EPUB"); aMediaDescriptor["FilterData"] <<= rFilterData; xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); + mxZipFile = packages::zip::ZipFileAccess::createWithURL(mxComponentContext, maTempFile.GetURL()); +} + +xmlDocPtr EPUBExportTest::parseExport(const OUString &rName) +{ + uno::Reference<io::XInputStream> xInputStream(mxZipFile->getByName(rName), uno::UNO_QUERY); + std::shared_ptr<SvStream> pStream(utl::UcbStreamHelper::CreateStream(xInputStream, true)); + return parseXmlStream(pStream.get()); } void EPUBExportTest::testOutlineLevel() @@ -92,11 +114,10 @@ void EPUBExportTest::testOutlineLevel() createDoc("outline-level.fodt", {}); // Make sure that the output is split into two. - uno::Reference<packages::zip::XZipFileAccess2> xNameAccess = packages::zip::ZipFileAccess::createWithURL(mxComponentContext, maTempFile.GetURL()); - CPPUNIT_ASSERT(xNameAccess->hasByName("OEBPS/sections/section0001.xhtml")); + CPPUNIT_ASSERT(mxZipFile->hasByName("OEBPS/sections/section0001.xhtml")); // This failed, output was a single section. - CPPUNIT_ASSERT(xNameAccess->hasByName("OEBPS/sections/section0002.xhtml")); - CPPUNIT_ASSERT(!xNameAccess->hasByName("OEBPS/sections/section0003.xhtml")); + CPPUNIT_ASSERT(mxZipFile->hasByName("OEBPS/sections/section0002.xhtml")); + CPPUNIT_ASSERT(!mxZipFile->hasByName("OEBPS/sections/section0003.xhtml")); } void EPUBExportTest::testMimetype() @@ -113,6 +134,10 @@ void EPUBExportTest::testMimetype() OString aActual(static_cast<const char *>(aMemoryStream.GetBuffer()) + 38, aExpected.getLength()); // This failed: actual data was some garbage, not the uncompressed mime type. CPPUNIT_ASSERT_EQUAL(aExpected, aActual); + + mpXmlDoc = parseExport("OEBPS/content.opf"); + // Default is EPUB3. + assertXPath(mpXmlDoc, "/opf:package", "version", "3.0"); } void EPUBExportTest::testEPUB2() @@ -124,13 +149,25 @@ void EPUBExportTest::testEPUB2() })); createDoc("hello.fodt", aFilterData); - uno::Reference<packages::zip::XZipFileAccess2> xNameAccess = packages::zip::ZipFileAccess::createWithURL(mxComponentContext, maTempFile.GetURL()); - uno::Reference<io::XInputStream> xInputStream(xNameAccess->getByName("OEBPS/content.opf"), uno::UNO_QUERY); - std::shared_ptr<SvStream> pStream(utl::UcbStreamHelper::CreateStream(xInputStream, true)); - xmlDocPtr pXmlDoc = parseXmlStream(pStream.get()); + mpXmlDoc = parseExport("OEBPS/content.opf"); // This was 3.0, EPUBVersion filter option was ignored and we always emitted EPUB3. - assertXPath(pXmlDoc, "/opf:package", "version", "2.0"); - xmlFreeDoc(pXmlDoc); + assertXPath(mpXmlDoc, "/opf:package", "version", "2.0"); +} + +void EPUBExportTest::testPageBreakSplit() +{ + uno::Sequence<beans::PropertyValue> aFilterData(comphelper::InitPropertySequence( + { + // Explicitly request split on page break (instead of on heading). + {"EPUBSplitMethod", uno::makeAny(static_cast<sal_Int32>(libepubgen::EPUB_SPLIT_METHOD_PAGE_BREAK))} + })); + createDoc("2pages.fodt", aFilterData); + + // Make sure that the output is split into two. + CPPUNIT_ASSERT(mxZipFile->hasByName("OEBPS/sections/section0001.xhtml")); + // This failed, output was a single section. + CPPUNIT_ASSERT(mxZipFile->hasByName("OEBPS/sections/section0002.xhtml")); + CPPUNIT_ASSERT(!mxZipFile->hasByName("OEBPS/sections/section0003.xhtml")); } CPPUNIT_TEST_SUITE_REGISTRATION(EPUBExportTest); diff --git a/writerperfect/qa/unit/data/writer/epubexport/2pages.fodt b/writerperfect/qa/unit/data/writer/epubexport/2pages.fodt new file mode 100644 index 000000000000..ee797e8ac237 --- /dev/null +++ b/writerperfect/qa/unit/data/writer/epubexport/2pages.fodt @@ -0,0 +1,14 @@ +<?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:paragraph-properties fo:break-before="page"/> + </style:style> + </office:automatic-styles> + <office:body> + <office:text text:use-soft-page-breaks="true"> + <text:p>First page</text:p> + <text:p text:style-name="P1">Second page</text:p> + </office:text> + </office:body> +</office:document> diff --git a/writerperfect/source/writer/EPUBExportFilter.cxx b/writerperfect/source/writer/EPUBExportFilter.cxx index ac16cd570198..778e6a4e51be 100644 --- a/writerperfect/source/writer/EPUBExportFilter.cxx +++ b/writerperfect/source/writer/EPUBExportFilter.cxx @@ -12,6 +12,7 @@ #include "config_libepubgen.h" #include <libepubgen/EPUBTextGenerator.h> +#include <libepubgen/libepubgen-decls.h> #include <com/sun/star/lang/XInitialization.hpp> #include <com/sun/star/uno/XComponentContext.hpp> @@ -35,6 +36,7 @@ EPUBExportFilter::EPUBExportFilter(const uno::Reference<uno::XComponentContext> sal_Bool EPUBExportFilter::filter(const uno::Sequence<beans::PropertyValue> &rDescriptor) { sal_Int32 nVersion = 30; + sal_Int32 nSplitMethod = libepubgen::EPUB_SPLIT_METHOD_HEADING; uno::Sequence<beans::PropertyValue> aFilterData; for (sal_Int32 i = 0; i < rDescriptor.getLength(); ++i) { @@ -49,13 +51,15 @@ sal_Bool EPUBExportFilter::filter(const uno::Sequence<beans::PropertyValue> &rDe { if (aFilterData[i].Name == "EPUBVersion") aFilterData[i].Value >>= nVersion; + else if (aFilterData[i].Name == "EPUBSplitMethod") + aFilterData[i].Value >>= nSplitMethod; } // Build the export filter chain: the package has direct access to the ZIP // file, the flat ODF filter has access to the doc model, everything else // is in-between. EPUBPackage aPackage(mxContext, rDescriptor); - libepubgen::EPUBTextGenerator aGenerator(&aPackage, libepubgen::EPUB_SPLIT_METHOD_HEADING + libepubgen::EPUBTextGenerator aGenerator(&aPackage, static_cast<libepubgen::EPUBSplitMethod>(nSplitMethod) #if LIBEPUBGEN_VERSION_SUPPORT , nVersion #endif |