Kaydet (Commit) 5ea92728 authored tarafından David Tardon's avatar David Tardon

upload libepubgen 0.1.1

Change-Id: Ib294f412055ef23a6ca5608675bc924dacae56f4
Reviewed-on: https://gerrit.libreoffice.org/55248Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarDavid Tardon <dtardon@redhat.com>
üst 06f819ba
......@@ -37,8 +37,8 @@ export EPOXY_SHA256SUM := 1d8668b0a259c709899e1c4bab62d756d9002d546ce4f59c9665e2
export EPOXY_TARBALL := libepoxy-1.3.1.tar.bz2
export EPM_SHA256SUM := b3fc4c5445de6c9a801504a3ea3efb2d4ea9d5a622c9427e716736e7713ddb91
export EPM_TARBALL := 3ade8cfe7e59ca8e65052644fed9fca4-epm-3.7.tar.gz
export EPUBGEN_SHA256SUM := 730bd1cbeee166334faadbc06c953a67b145c3c4754a3b503482066dae4cd633
export EPUBGEN_TARBALL := libepubgen-0.1.0.tar.bz2
export EPUBGEN_SHA256SUM := 03e084b994cbeffc8c3dd13303b2cb805f44d8f2c3b79f7690d7e3fc7f6215ad
export EPUBGEN_TARBALL := libepubgen-0.1.1.tar.xz
export ETONYEK_SHA256SUM := 9dc92347aee0cc9ed57b175a3e21f9d96ebe55d30fecb10e841d1050794ed82d
export ETONYEK_VERSION_MICRO := 8
export ETONYEK_TARBALL := libetonyek-0.1.$(ETONYEK_VERSION_MICRO).tar.xz
......
From 16c4e93af6d5eb9d021a671c54af664edc120df9 Mon Sep 17 00:00:00 2001
From: Mark Hung <marklh9@gmail.com>
Date: Mon, 23 Apr 2018 01:24:48 +0800
Subject: [PATCH] Enclose <span> with <ruby> if text:ruby-text is set.
---
src/lib/EPUBHTMLGenerator.cpp | 22 ++++++++++++++++++++++
src/test/EPUBTextGeneratorTest.cpp | 25 +++++++++++++++++++++++++
2 files changed, 47 insertions(+)
diff --git a/src/lib/EPUBHTMLGenerator.cpp b/src/lib/EPUBHTMLGenerator.cpp
index 0080816..a4467a9 100644
--- a/src/lib/EPUBHTMLGenerator.cpp
+++ b/src/lib/EPUBHTMLGenerator.cpp
@@ -397,6 +397,7 @@ struct EPUBHTMLGeneratorImpl
, m_linkPropertiesStack()
, m_paragraphAttributesStack()
, m_spanAttributesStack()
+ , m_rubyText()
, m_stylesMethod(stylesMethod)
, m_layoutMethod(layoutMethod)
, m_actualSink()
@@ -500,6 +501,9 @@ struct EPUBHTMLGeneratorImpl
std::stack<RVNGPropertyList> m_paragraphAttributesStack;
std::stack<RVNGPropertyList> m_spanAttributesStack;
+ /// This is set when the span has ruby text and should be wrapped in <ruby></ruby>.
+ std::string m_rubyText;
+
EPUBStylesMethod m_stylesMethod;
EPUBLayoutMethod m_layoutMethod;
@@ -743,6 +747,14 @@ void EPUBHTMLGenerator::openSpan(const RVNGPropertyList &propList)
attrs.insert("style", m_impl->m_spanManager.getStyle(propList, false).c_str());
break;
}
+
+ const librevenge::RVNGProperty *rubyText = propList["text:ruby-text"];
+ if (rubyText)
+ {
+ m_impl->m_rubyText = rubyText->getStr().cstr();
+ m_impl->output(false).openElement("ruby", attrs);
+ }
+
m_impl->output(false).openElement("span", attrs);
librevenge::RVNGPropertyList::Iter i(attrs);
@@ -761,6 +773,16 @@ void EPUBHTMLGenerator::closeSpan()
m_impl->m_spanAttributesStack.pop();
m_impl->output().closeElement("span");
+
+ if (m_impl->m_rubyText.length())
+ {
+ m_impl->output().openElement("rt");
+ m_impl->output().insertCharacters(m_impl->m_rubyText.c_str());
+ m_impl->output().closeElement("rt");
+ m_impl->output().closeElement("ruby");
+ m_impl->m_hasText = true;
+ m_impl->m_rubyText.clear();
+ }
}
void EPUBHTMLGenerator::openLink(const RVNGPropertyList &propList)
diff --git a/src/test/EPUBTextGeneratorTest.cpp b/src/test/EPUBTextGeneratorTest.cpp
index f03824f..61c7cac 100644
--- a/src/test/EPUBTextGeneratorTest.cpp
+++ b/src/test/EPUBTextGeneratorTest.cpp
@@ -240,6 +240,7 @@ private:
CPPUNIT_TEST(testSplitOnHeadingInPageSpan);
CPPUNIT_TEST(testSplitOnSizeInPageSpan);
CPPUNIT_TEST(testManyWritingModes);
+ CPPUNIT_TEST(testRubyElements);
CPPUNIT_TEST_SUITE_END();
private:
@@ -284,6 +285,7 @@ private:
void testSplitOnHeadingInPageSpan();
void testSplitOnSizeInPageSpan();
void testManyWritingModes();
+ void testRubyElements();
/// Asserts that exactly one xpath exists in buffer, and its content equals content.
void assertXPathContent(xmlBufferPtr buffer, const std::string &xpath, const std::string &content);
@@ -1507,6 +1509,29 @@ void EPUBTextGeneratorTest::testManyWritingModes()
assertXPath(package.m_streams["OEBPS/sections/section0002.xhtml"], "//xhtml:body", "class", "body1");
}
+void EPUBTextGeneratorTest::testRubyElements()
+{
+ StringEPUBPackage package;
+ libepubgen::EPUBTextGenerator generator(&package);
+ generator.startDocument(librevenge::RVNGPropertyList());
+ generator.openParagraph(librevenge::RVNGPropertyList());
+ {
+ librevenge::RVNGPropertyList span;
+ span.insert("text:ruby-text", "ruby text");
+ generator.openSpan(span);
+ generator.insertText("base text");
+ generator.closeSpan();
+ }
+ generator.closeParagraph();
+ generator.endDocument();
+
+ // Expects: <ruby><span>base text</span><rt>ruby text</rt></ruby>
+ CPPUNIT_ASSERT_XPATH(package.m_streams["OEBPS/sections/section0001.xhtml"], "//xhtml:ruby", 1);
+ CPPUNIT_ASSERT_XPATH_CONTENT(package.m_streams["OEBPS/sections/section0001.xhtml"], "//xhtml:ruby/xhtml:rt", "ruby text");
+ CPPUNIT_ASSERT_XPATH_CONTENT(package.m_streams["OEBPS/sections/section0001.xhtml"], "//xhtml:ruby/xhtml:span", "base text");
+}
+
+
CPPUNIT_TEST_SUITE_REGISTRATION(EPUBTextGeneratorTest);
}
--
2.14.1
From 9b1c3fd42fa256b58dfb4dedd070954406c25596 Mon Sep 17 00:00:00 2001
From: Mark Hung <marklh9@gmail.com>
Date: Mon, 19 Mar 2018 20:36:11 +0800
Subject: [PATCH 1/3] Support writing-mode for reflowable layout method.
Convert style:writing-mode in page properties to css style for
HTML body element. The class names of body elements will be like
"body0".
---
src/lib/EPUBGenerator.cpp | 1 +
src/lib/EPUBHTMLGenerator.cpp | 18 +++++++++++++--
src/lib/EPUBSpanStyleManager.cpp | 45 ++++++++++++++++++++++++++++++++------
src/lib/EPUBSpanStyleManager.h | 14 ++++++++----
src/test/EPUBTextGeneratorTest.cpp | 25 +++++++++++++++++++++
5 files changed, 90 insertions(+), 13 deletions(-)
diff --git a/src/lib/EPUBGenerator.cpp b/src/lib/EPUBGenerator.cpp
index 83f3f40..56db4dc 100644
--- a/src/lib/EPUBGenerator.cpp
+++ b/src/lib/EPUBGenerator.cpp
@@ -122,6 +122,7 @@ void EPUBGenerator::startNewHtmlFile()
if (m_layoutMethod == EPUB_LAYOUT_METHOD_FIXED && m_currentHtml)
m_currentHtml->getPageProperties(pageProperties);
m_currentHtml = m_htmlManager.create(m_imageManager, m_fontManager, m_listStyleManager, m_paragraphStyleManager, m_spanStyleManager, m_tableStyleManager, m_stylesheetPath, m_stylesMethod, m_layoutMethod, m_version);
+
if (m_layoutMethod == EPUB_LAYOUT_METHOD_FIXED)
m_currentHtml->setPageProperties(pageProperties);
diff --git a/src/lib/EPUBHTMLGenerator.cpp b/src/lib/EPUBHTMLGenerator.cpp
index 342213e..d5cc0d2 100644
--- a/src/lib/EPUBHTMLGenerator.cpp
+++ b/src/lib/EPUBHTMLGenerator.cpp
@@ -600,6 +600,20 @@ void EPUBHTMLGenerator::endDocument()
RVNGPropertyList bodyAttrs;
if (m_impl->m_version >= 30)
bodyAttrs.insert("xmlns:epub", "http://www.idpf.org/2007/ops");
+
+ if (m_impl->m_actualPageProperties["style:writing-mode"])
+ {
+ switch (m_impl->m_stylesMethod)
+ {
+ case EPUB_STYLES_METHOD_CSS:
+ bodyAttrs.insert("class", m_impl->m_spanManager.getClass(m_impl->m_actualPageProperties, true).c_str());
+ break;
+ case EPUB_STYLES_METHOD_INLINE:
+ bodyAttrs.insert("style", m_impl->m_spanManager.getStyle(m_impl->m_actualPageProperties, true).c_str());
+ break;
+ }
+ }
+
m_impl->m_document.openElement("body", bodyAttrs);
m_impl->flushUnsent(m_impl->m_document);
m_impl->m_document.closeElement("body");
@@ -710,10 +724,10 @@ void EPUBHTMLGenerator::openSpan(const RVNGPropertyList &propList)
switch (m_impl->m_stylesMethod)
{
case EPUB_STYLES_METHOD_CSS:
- attrs.insert("class", m_impl->m_spanManager.getClass(propList).c_str());
+ attrs.insert("class", m_impl->m_spanManager.getClass(propList, false).c_str());
break;
case EPUB_STYLES_METHOD_INLINE:
- attrs.insert("style", m_impl->m_spanManager.getStyle(propList).c_str());
+ attrs.insert("style", m_impl->m_spanManager.getStyle(propList, false).c_str());
break;
}
m_impl->output(false).openElement("span", attrs);
diff --git a/src/lib/EPUBSpanStyleManager.cpp b/src/lib/EPUBSpanStyleManager.cpp
index e25fa26..ded34ba 100644
--- a/src/lib/EPUBSpanStyleManager.cpp
+++ b/src/lib/EPUBSpanStyleManager.cpp
@@ -21,7 +21,7 @@ namespace libepubgen
using librevenge::RVNGPropertyList;
-std::string EPUBSpanStyleManager::getClass(RVNGPropertyList const &pList)
+std::string EPUBSpanStyleManager::getClass(RVNGPropertyList const &pList, bool bIsBody)
{
if (pList["librevenge:span-id"])
{
@@ -31,20 +31,31 @@ std::string EPUBSpanStyleManager::getClass(RVNGPropertyList const &pList)
}
EPUBCSSProperties content;
- extractProperties(pList, content);
+ if (bIsBody)
+ extractBodyProperties(pList, content);
+ else
+ extractSpanProperties(pList, content);
+
ContentNameMap_t::const_iterator it = m_contentNameMap.find(content);
if (it != m_contentNameMap.end())
return it->second;
std::stringstream s;
- s << "span" << m_contentNameMap.size();
+ if (bIsBody)
+ s << "body" << (m_numberBody.next() - 1);
+ else
+ s << "span" << (m_numberSpan.next() - 1);
+
m_contentNameMap[content]=s.str();
return s.str();
}
-std::string EPUBSpanStyleManager::getStyle(RVNGPropertyList const &pList)
+std::string EPUBSpanStyleManager::getStyle(RVNGPropertyList const &pList, bool bIsBody)
{
EPUBCSSProperties content;
- extractProperties(pList, content);
+ if (bIsBody)
+ extractBodyProperties(pList, content);
+ else
+ extractSpanProperties(pList, content);
std::stringstream s;
for (const auto &property : content)
@@ -62,7 +73,7 @@ void EPUBSpanStyleManager::defineSpan(RVNGPropertyList const &propList)
int id=propList["librevenge:span-id"]->getInt();
RVNGPropertyList pList(propList);
pList.remove("librevenge:span-id");
- m_idNameMap[id]=getClass(pList);
+ m_idNameMap[id]=getClass(pList, false);
}
void EPUBSpanStyleManager::send(EPUBCSSSink &out)
@@ -75,7 +86,7 @@ void EPUBSpanStyleManager::send(EPUBCSSSink &out)
}
}
-void EPUBSpanStyleManager::extractProperties(RVNGPropertyList const &pList, EPUBCSSProperties &cssProps) const
+void EPUBSpanStyleManager::extractSpanProperties(RVNGPropertyList const &pList, EPUBCSSProperties &cssProps) const
{
if (pList["fo:background-color"])
cssProps["background-color"] = pList["fo:background-color"]->getStr().cstr();
@@ -227,6 +238,26 @@ void EPUBSpanStyleManager::extractTextPosition(char const *value, EPUBCSSPropert
}
}
+void EPUBSpanStyleManager::extractBodyProperties(RVNGPropertyList const &pList, EPUBCSSProperties &cssProps) const
+{
+ if (pList["style:writing-mode"])
+ {
+ std::string mode = pList["style:writing-mode"]->getStr().cstr();
+ if (mode == "tb-rl" || mode == "tb")
+ mode = "vertical-rl";
+ else if (mode == "tb-lr")
+ mode = "vertical-lr";
+ else // For the rest: lr, lr-tb, rl, rl-tb
+ {
+ mode = "horizontal-tb";
+ cssProps["direction"] = (mode == "rl-tb" || mode == "rl")?"rtl":"ltr";
+ }
+
+ cssProps["-epub-writing-mode"] = mode;
+ cssProps["-webkit-writing-mode"] = mode;
+ cssProps["writing-mode"] = mode;
+ }
+}
}
/* vim:set shiftwidth=2 softtabstop=2 expandtab: */
diff --git a/src/lib/EPUBSpanStyleManager.h b/src/lib/EPUBSpanStyleManager.h
index ec9d0e5..6c18392 100644
--- a/src/lib/EPUBSpanStyleManager.h
+++ b/src/lib/EPUBSpanStyleManager.h
@@ -19,6 +19,7 @@
#include <librevenge/librevenge.h>
#include "EPUBCSSProperties.h"
+#include "EPUBCounter.h"
namespace libepubgen
{
@@ -32,7 +33,7 @@ class EPUBSpanStyleManager
public:
//! constructor
- EPUBSpanStyleManager() : m_contentNameMap(), m_idNameMap()
+ EPUBSpanStyleManager() : m_contentNameMap(), m_idNameMap(), m_numberSpan(), m_numberBody()
{
}
//! destructor
@@ -42,14 +43,16 @@ public:
//! define a span style
void defineSpan(librevenge::RVNGPropertyList const &pList);
//! returns the class name corresponding to a propertylist
- std::string getClass(librevenge::RVNGPropertyList const &pList);
+ std::string getClass(librevenge::RVNGPropertyList const &pList, bool bIsBody);
//! returns the style string corresponding to a propertylist
- std::string getStyle(librevenge::RVNGPropertyList const &pList);
+ std::string getStyle(librevenge::RVNGPropertyList const &pList, bool bIsBody);
//! send the data to the sink
void send(EPUBCSSSink &out);
protected:
//! convert a property list into a CSS property map
- void extractProperties(librevenge::RVNGPropertyList const &pList, EPUBCSSProperties &cssProps) const;
+ void extractSpanProperties(librevenge::RVNGPropertyList const &pList, EPUBCSSProperties &cssProps) const;
+ //! Extract body styles from a property list into a CSS property map
+ void extractBodyProperties(librevenge::RVNGPropertyList const &pList, EPUBCSSProperties &cssProps) const;
//! add data corresponding to a text position into the map
void extractTextPosition(char const *value, EPUBCSSProperties &cssProps) const;
//! add data corresponding to the line decoration into the map
@@ -59,6 +62,9 @@ protected:
//! a map id -> name
std::map<int, std::string> m_idNameMap;
+ EPUBCounter m_numberSpan;
+ EPUBCounter m_numberBody;
+
private:
EPUBSpanStyleManager(EPUBSpanStyleManager const &orig);
EPUBSpanStyleManager operator=(EPUBSpanStyleManager const &orig);
diff --git a/src/test/EPUBTextGeneratorTest.cpp b/src/test/EPUBTextGeneratorTest.cpp
index ddf0c90..cf5e35f 100644
--- a/src/test/EPUBTextGeneratorTest.cpp
+++ b/src/test/EPUBTextGeneratorTest.cpp
@@ -235,6 +235,7 @@ private:
CPPUNIT_TEST(testFixedLayoutSpine);
CPPUNIT_TEST(testPageBreak);
CPPUNIT_TEST(testPageBreakImage);
+ CPPUNIT_TEST(testWritingMode);
CPPUNIT_TEST_SUITE_END();
private:
@@ -274,6 +275,7 @@ private:
void testFixedLayoutSpine();
void testPageBreak();
void testPageBreakImage();
+ void testWritingMode();
/// Asserts that exactly one xpath exists in buffer, and its content equals content.
void assertXPathContent(xmlBufferPtr buffer, const std::string &xpath, const std::string &content);
@@ -1350,6 +1352,29 @@ void EPUBTextGeneratorTest::testPageBreakImage()
CPPUNIT_ASSERT(package.m_streams.find("OEBPS/sections/section0002.xhtml") != package.m_streams.end());
}
+void EPUBTextGeneratorTest::testWritingMode()
+{
+ StringEPUBPackage package;
+ libepubgen::EPUBTextGenerator generator(&package);
+ generator.setOption(libepubgen::EPUB_GENERATOR_OPTION_SPLIT, libepubgen::EPUB_SPLIT_METHOD_PAGE_BREAK);
+ generator.startDocument(librevenge::RVNGPropertyList());
+
+ {
+ librevenge::RVNGPropertyList page;
+ page.insert("style:writing-mode", "tb");
+ generator.openPageSpan(page);
+
+ librevenge::RVNGPropertyList para;
+ generator.openParagraph(para);
+ generator.insertText("Para1");
+ generator.closeParagraph();
+ generator.closePageSpan();
+ }
+ generator.endDocument();
+ assertCss(package.m_cssStreams["OEBPS/styles/stylesheet.css"], ".body0", "writing-mode: vertical-rl", true);
+ assertXPath(package.m_streams["OEBPS/sections/section0001.xhtml"], "//xhtml:body", "class", "body0");
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(EPUBTextGeneratorTest);
}
--
2.14.1
From c3bd3bee2f6e01f0b5f5a8fb376ce175573a8e96 Mon Sep 17 00:00:00 2001
From: Mark Hung <marklh9@gmail.com>
Date: Sat, 24 Mar 2018 12:50:12 +0800
Subject: [PATCH 2/3] Always keep page properties when splitting the HTML file.
Those page properties shall be changed only via openPageSpan.
It was kept only when the layout out method is EPUB_LAYOUT_METHOD_FIXED
before.
---
src/lib/EPUBGenerator.cpp | 9 ++--
src/test/EPUBTextGeneratorTest.cpp | 98 ++++++++++++++++++++++++++++++++++++--
2 files changed, 99 insertions(+), 8 deletions(-)
diff --git a/src/lib/EPUBGenerator.cpp b/src/lib/EPUBGenerator.cpp
index 56db4dc..110667f 100644
--- a/src/lib/EPUBGenerator.cpp
+++ b/src/lib/EPUBGenerator.cpp
@@ -110,21 +110,20 @@ void EPUBGenerator::setDocumentMetaData(const RVNGPropertyList &props)
void EPUBGenerator::startNewHtmlFile()
{
// close the current HTML file
+ librevenge::RVNGPropertyList pageProperties;
if (bool(m_currentHtml))
{
endHtmlFile();
m_currentHtml->endDocument();
+ m_currentHtml->getPageProperties(pageProperties);
}
m_splitGuard.onSplit();
- librevenge::RVNGPropertyList pageProperties;
- if (m_layoutMethod == EPUB_LAYOUT_METHOD_FIXED && m_currentHtml)
- m_currentHtml->getPageProperties(pageProperties);
m_currentHtml = m_htmlManager.create(m_imageManager, m_fontManager, m_listStyleManager, m_paragraphStyleManager, m_spanStyleManager, m_tableStyleManager, m_stylesheetPath, m_stylesMethod, m_layoutMethod, m_version);
- if (m_layoutMethod == EPUB_LAYOUT_METHOD_FIXED)
- m_currentHtml->setPageProperties(pageProperties);
+ // Splitted html file should keep the same page property.
+ m_currentHtml->setPageProperties(pageProperties);
// restore state in the new file
m_currentHtml->startDocument(m_documentProps);
diff --git a/src/test/EPUBTextGeneratorTest.cpp b/src/test/EPUBTextGeneratorTest.cpp
index cf5e35f..0946408 100644
--- a/src/test/EPUBTextGeneratorTest.cpp
+++ b/src/test/EPUBTextGeneratorTest.cpp
@@ -235,7 +235,10 @@ private:
CPPUNIT_TEST(testFixedLayoutSpine);
CPPUNIT_TEST(testPageBreak);
CPPUNIT_TEST(testPageBreakImage);
- CPPUNIT_TEST(testWritingMode);
+ CPPUNIT_TEST(testPageSpanProperties);
+ CPPUNIT_TEST(testSplitOnPageBreakInPageSpan);
+ CPPUNIT_TEST(testSplitOnHeadingInPageSpan);
+ CPPUNIT_TEST(testSplitOnSizeInPageSpan);
CPPUNIT_TEST_SUITE_END();
private:
@@ -275,7 +278,10 @@ private:
void testFixedLayoutSpine();
void testPageBreak();
void testPageBreakImage();
- void testWritingMode();
+ void testPageSpanProperties();
+ void testSplitOnPageBreakInPageSpan();
+ void testSplitOnHeadingInPageSpan();
+ void testSplitOnSizeInPageSpan();
/// Asserts that exactly one xpath exists in buffer, and its content equals content.
void assertXPathContent(xmlBufferPtr buffer, const std::string &xpath, const std::string &content);
@@ -1352,7 +1358,7 @@ void EPUBTextGeneratorTest::testPageBreakImage()
CPPUNIT_ASSERT(package.m_streams.find("OEBPS/sections/section0002.xhtml") != package.m_streams.end());
}
-void EPUBTextGeneratorTest::testWritingMode()
+void EPUBTextGeneratorTest::testPageSpanProperties()
{
StringEPUBPackage package;
libepubgen::EPUBTextGenerator generator(&package);
@@ -1368,11 +1374,97 @@ void EPUBTextGeneratorTest::testWritingMode()
generator.openParagraph(para);
generator.insertText("Para1");
generator.closeParagraph();
+ }
+ generator.endDocument();
+ assertCss(package.m_cssStreams["OEBPS/styles/stylesheet.css"], ".body0", "writing-mode: vertical-rl", true);
+ assertXPath(package.m_streams["OEBPS/sections/section0001.xhtml"], "//xhtml:body", "class", "body0");
+}
+
+void EPUBTextGeneratorTest::testSplitOnPageBreakInPageSpan()
+{
+ StringEPUBPackage package;
+ libepubgen::EPUBTextGenerator generator(&package);
+ generator.setOption(libepubgen::EPUB_GENERATOR_OPTION_SPLIT, libepubgen::EPUB_SPLIT_METHOD_PAGE_BREAK);
+ generator.startDocument(librevenge::RVNGPropertyList());
+
+ {
+ librevenge::RVNGPropertyList page;
+ page.insert("style:writing-mode", "tb");
+ generator.openPageSpan(page);
+
+ librevenge::RVNGPropertyList para;
+ generator.openParagraph(para);
+ generator.insertText("Para1");
+ generator.closeParagraph();
+ // Splitting a new html file inside the page span, the writing-mode shall not change.
+ para.insert("fo:break-before", "page");
+ generator.openParagraph(para);
+ generator.insertText("Para2");
+ generator.closeParagraph();
+ generator.closePageSpan();
+ }
+ generator.endDocument();
+ assertCss(package.m_cssStreams["OEBPS/styles/stylesheet.css"], ".body0", "writing-mode: vertical-rl", true);
+ assertXPath(package.m_streams["OEBPS/sections/section0001.xhtml"], "//xhtml:body", "class", "body0");
+ assertXPath(package.m_streams["OEBPS/sections/section0002.xhtml"], "//xhtml:body", "class", "body0");
+}
+
+void EPUBTextGeneratorTest::testSplitOnHeadingInPageSpan()
+{
+ StringEPUBPackage package;
+ libepubgen::EPUBTextGenerator generator(&package);
+ generator.setOption(libepubgen::EPUB_GENERATOR_OPTION_SPLIT, libepubgen::EPUB_SPLIT_METHOD_HEADING);
+ generator.startDocument(librevenge::RVNGPropertyList());
+
+ {
+ librevenge::RVNGPropertyList page;
+ page.insert("style:writing-mode", "tb");
+ generator.openPageSpan(page);
+
+ librevenge::RVNGPropertyList para;
+ para.insert("text:outline-level", "1");
+ generator.openParagraph(para);
+ generator.insertText("Chapter1");
+ generator.closeParagraph();
+ // Splitting a new html file inside the page span, the writing-mode shall not change.
+ generator.openParagraph(para);
+ generator.insertText("Chapter2");
+ generator.closeParagraph();
+ generator.closePageSpan();
+ }
+ generator.endDocument();
+ assertCss(package.m_cssStreams["OEBPS/styles/stylesheet.css"], ".body0", "writing-mode: vertical-rl", true);
+ assertXPath(package.m_streams["OEBPS/sections/section0001.xhtml"], "//xhtml:body", "class", "body0");
+ assertXPath(package.m_streams["OEBPS/sections/section0002.xhtml"], "//xhtml:body", "class", "body0");
+}
+
+void EPUBTextGeneratorTest::testSplitOnSizeInPageSpan()
+{
+ StringEPUBPackage package;
+ libepubgen::EPUBTextGenerator generator(&package);
+ generator.setOption(libepubgen::EPUB_GENERATOR_OPTION_SPLIT, libepubgen::EPUB_SPLIT_METHOD_SIZE);
+ generator.setSplitSize(5);
+ generator.startDocument(librevenge::RVNGPropertyList());
+
+ {
+ librevenge::RVNGPropertyList page;
+ page.insert("style:writing-mode", "tb");
+ generator.openPageSpan(page);
+
+ librevenge::RVNGPropertyList para;
+ generator.openParagraph(para);
+ generator.insertText("Hello!");
+ generator.closeParagraph();
+ // Splitting a new html file inside the page span, the writing-mode shall not change.
+ generator.openParagraph(para);
+ generator.insertText("Hello!");
+ generator.closeParagraph();
generator.closePageSpan();
}
generator.endDocument();
assertCss(package.m_cssStreams["OEBPS/styles/stylesheet.css"], ".body0", "writing-mode: vertical-rl", true);
assertXPath(package.m_streams["OEBPS/sections/section0001.xhtml"], "//xhtml:body", "class", "body0");
+ assertXPath(package.m_streams["OEBPS/sections/section0002.xhtml"], "//xhtml:body", "class", "body0");
}
CPPUNIT_TEST_SUITE_REGISTRATION(EPUBTextGeneratorTest);
--
2.14.1
From 715786e10deaa6849a6e46b5a9884edde44e194b Mon Sep 17 00:00:00 2001
From: Mark Hung <marklh9@gmail.com>
Date: Sun, 25 Mar 2018 10:27:07 +0800
Subject: [PATCH 3/3] Ensure page properties in the page span works.
As the page properties are converted to CSS styles of the
body element, this patch force it to start a new HTML file
when openPageSpan is invoked to open the second page span.
This ensures that page properties in every page span works,
even there are multiple page spans between intentional HTML
page splits such as on size, on headings, or on page breaks.
---
src/lib/EPUBGenerator.cpp | 4 +++-
src/lib/EPUBSplitGuard.cpp | 19 ++++++++++++++++++-
src/lib/EPUBSplitGuard.h | 7 ++++++-
src/lib/EPUBTextGenerator.cpp | 5 +++++
src/test/EPUBTextGeneratorTest.cpp | 38 ++++++++++++++++++++++++++++++++++++++
5 files changed, 70 insertions(+), 3 deletions(-)
diff --git a/src/lib/EPUBGenerator.cpp b/src/lib/EPUBGenerator.cpp
index 110667f..9e0c972 100644
--- a/src/lib/EPUBGenerator.cpp
+++ b/src/lib/EPUBGenerator.cpp
@@ -44,7 +44,7 @@ EPUBGenerator::EPUBGenerator(EPUBPackage *const package, int version)
, m_documentProps()
, m_metadata()
, m_currentHtml()
- , m_splitGuard(EPUB_SPLIT_METHOD_PAGE_BREAK)
+ , m_splitGuard(EPUB_SPLIT_METHOD_PAGE_BREAK,true)
, m_version(version)
, m_stylesMethod(EPUB_STYLES_METHOD_CSS)
, m_layoutMethod(EPUB_LAYOUT_METHOD_REFLOWABLE)
@@ -173,6 +173,8 @@ void EPUBGenerator::setLayoutMethod(EPUBLayoutMethod layout)
if (m_layoutMethod == EPUB_LAYOUT_METHOD_FIXED)
// Fixed layout implies split on page break.
m_splitGuard.setSplitMethod(EPUB_SPLIT_METHOD_PAGE_BREAK);
+
+ m_splitGuard.setSplitOnSecondPageSpan(m_layoutMethod == EPUB_LAYOUT_METHOD_REFLOWABLE);
}
void EPUBGenerator::writeContainer()
diff --git a/src/lib/EPUBSplitGuard.cpp b/src/lib/EPUBSplitGuard.cpp
index 4f7531d..5bee515 100644
--- a/src/lib/EPUBSplitGuard.cpp
+++ b/src/lib/EPUBSplitGuard.cpp
@@ -15,8 +15,10 @@ namespace libepubgen
static const unsigned DEFAULT_SPLIT_HEADING_LEVEL = 1;
static const unsigned DEFAULT_SPLIT_SIZE = 1 << 16;
-EPUBSplitGuard::EPUBSplitGuard(const EPUBSplitMethod method)
+EPUBSplitGuard::EPUBSplitGuard(const EPUBSplitMethod method,bool splitOnSecondPageSpan)
: m_method(method)
+ , m_splitOnSecondPageSpan(splitOnSecondPageSpan)
+ , m_htmlEverInPageSpan(false)
, m_headingLevel(DEFAULT_SPLIT_HEADING_LEVEL)
, m_currentHeadingLevel(0)
, m_size(DEFAULT_SPLIT_SIZE)
@@ -25,6 +27,11 @@ EPUBSplitGuard::EPUBSplitGuard(const EPUBSplitMethod method)
{
}
+void EPUBSplitGuard::setHtmlEverInPageSpan(bool value)
+{
+ m_htmlEverInPageSpan = value;
+}
+
void EPUBSplitGuard::setSplitHeadingLevel(const unsigned level)
{
m_headingLevel = level;
@@ -45,6 +52,11 @@ void EPUBSplitGuard::setSplitMethod(EPUBSplitMethod method)
m_method = method;
}
+void EPUBSplitGuard::setSplitOnSecondPageSpan(bool value)
+{
+ m_splitOnSecondPageSpan = value;
+}
+
void EPUBSplitGuard::openLevel()
{
++m_nestingLevel;
@@ -70,6 +82,11 @@ bool EPUBSplitGuard::splitOnHeading(const unsigned level) const
return canSplit(EPUB_SPLIT_METHOD_HEADING) && (m_headingLevel >= level);
}
+bool EPUBSplitGuard::splitOnSecondPageSpan() const
+{
+ return m_splitOnSecondPageSpan && m_htmlEverInPageSpan;
+}
+
bool EPUBSplitGuard::inHeading(bool any) const
{
if (!m_currentHeadingLevel)
diff --git a/src/lib/EPUBSplitGuard.h b/src/lib/EPUBSplitGuard.h
index ff55846..a55bad3 100644
--- a/src/lib/EPUBSplitGuard.h
+++ b/src/lib/EPUBSplitGuard.h
@@ -18,13 +18,15 @@ namespace libepubgen
class EPUBSplitGuard
{
public:
- explicit EPUBSplitGuard(EPUBSplitMethod method);
+ explicit EPUBSplitGuard(EPUBSplitMethod method,bool splitOnSecondPageSpan);
void setSplitHeadingLevel(unsigned level);
void setCurrentHeadingLevel(unsigned level);
void setSplitSize(unsigned size);
+ void setHtmlEverInPageSpan(bool value);
/// Allows overwriting the value given in the constructor.
void setSplitMethod(EPUBSplitMethod method);
+ void setSplitOnSecondPageSpan(bool value);
void openLevel();
void closeLevel();
@@ -32,6 +34,7 @@ public:
bool splitOnPageBreak() const;
bool splitOnHeading(unsigned level) const;
+ bool splitOnSecondPageSpan() const;
bool inHeading(bool any) const;
bool splitOnSize() const;
@@ -42,6 +45,8 @@ private:
private:
EPUBSplitMethod m_method;
+ bool m_splitOnSecondPageSpan;
+ bool m_htmlEverInPageSpan;
unsigned m_headingLevel;
unsigned m_currentHeadingLevel;
unsigned m_size;
diff --git a/src/lib/EPUBTextGenerator.cpp b/src/lib/EPUBTextGenerator.cpp
index 8e88adb..db9d360 100644
--- a/src/lib/EPUBTextGenerator.cpp
+++ b/src/lib/EPUBTextGenerator.cpp
@@ -110,6 +110,7 @@ void EPUBTextGenerator::Impl::startHtmlFile()
void EPUBTextGenerator::Impl::endHtmlFile()
{
+ getSplitGuard().setHtmlEverInPageSpan(false);
if (m_inPageSpan)
getHtml()->openPageSpan(m_pageSpanProps);
if (bool(m_currentHeader))
@@ -206,10 +207,14 @@ void EPUBTextGenerator::openPageSpan(const librevenge::RVNGPropertyList &propLis
{
assert(!m_impl->m_inPageSpan);
+ if (m_impl->getSplitGuard().splitOnSecondPageSpan())
+ m_impl->startNewHtmlFile();
+
m_impl->m_inPageSpan = true;
m_impl->m_pageSpanProps = propList;
m_impl->getHtml()->openPageSpan(propList);
+ m_impl->getSplitGuard().setHtmlEverInPageSpan(true);
}
void EPUBTextGenerator::closePageSpan()
diff --git a/src/test/EPUBTextGeneratorTest.cpp b/src/test/EPUBTextGeneratorTest.cpp
index 0946408..b5e43a5 100644
--- a/src/test/EPUBTextGeneratorTest.cpp
+++ b/src/test/EPUBTextGeneratorTest.cpp
@@ -239,6 +239,7 @@ private:
CPPUNIT_TEST(testSplitOnPageBreakInPageSpan);
CPPUNIT_TEST(testSplitOnHeadingInPageSpan);
CPPUNIT_TEST(testSplitOnSizeInPageSpan);
+ CPPUNIT_TEST(testManyWritingModes);
CPPUNIT_TEST_SUITE_END();
private:
@@ -282,6 +283,7 @@ private:
void testSplitOnPageBreakInPageSpan();
void testSplitOnHeadingInPageSpan();
void testSplitOnSizeInPageSpan();
+ void testManyWritingModes();
/// Asserts that exactly one xpath exists in buffer, and its content equals content.
void assertXPathContent(xmlBufferPtr buffer, const std::string &xpath, const std::string &content);
@@ -1467,6 +1469,42 @@ void EPUBTextGeneratorTest::testSplitOnSizeInPageSpan()
assertXPath(package.m_streams["OEBPS/sections/section0002.xhtml"], "//xhtml:body", "class", "body0");
}
+void EPUBTextGeneratorTest::testManyWritingModes()
+{
+ StringEPUBPackage package;
+ libepubgen::EPUBTextGenerator generator(&package);
+ generator.setOption(libepubgen::EPUB_GENERATOR_OPTION_SPLIT, libepubgen::EPUB_SPLIT_METHOD_PAGE_BREAK);
+ generator.startDocument(librevenge::RVNGPropertyList());
+
+ {
+ librevenge::RVNGPropertyList page;
+ page.insert("style:writing-mode", "tb");
+ generator.openPageSpan(page);
+
+ librevenge::RVNGPropertyList para;
+ generator.openParagraph(para);
+ generator.insertText("Para1");
+ generator.closeParagraph();
+ generator.closePageSpan();
+ }
+ {
+ librevenge::RVNGPropertyList page;
+ page.insert("style:writing-mode", "lr");
+ generator.openPageSpan(page);
+
+ librevenge::RVNGPropertyList para;
+ generator.openParagraph(para);
+ generator.insertText("Para1");
+ generator.closeParagraph();
+ generator.closePageSpan();
+ }
+ generator.endDocument();
+ assertCss(package.m_cssStreams["OEBPS/styles/stylesheet.css"], ".body0", "writing-mode: vertical-rl", true);
+ assertCss(package.m_cssStreams["OEBPS/styles/stylesheet.css"], ".body1", "writing-mode: horizontal-tb", true);
+ assertXPath(package.m_streams["OEBPS/sections/section0001.xhtml"], "//xhtml:body", "class", "body0");
+ assertXPath(package.m_streams["OEBPS/sections/section0002.xhtml"], "//xhtml:body", "class", "body1");
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(EPUBTextGeneratorTest);
}
--
2.14.1
......@@ -8,16 +8,6 @@
#
epubgen_patches :=
# Backport of <https://sourceforge.net/p/libepubgen/code/ci/006848cb62225647c418d5143d4e88a9d73829da/>.
epubgen_patches += libepubgen-epub3.patch.1
# Backport of <https://sourceforge.net/p/libepubgen/code/ci/9a284081eea4a95235a6d6a6a50cbe3f7ad323ba/>.
epubgen_patches += 0001-Support-writing-mode-for-reflowable-layout-method.patch.1
# Backport of <https://sourceforge.net/p/libepubgen/code/ci/0318031b9094b9180d1d391d0ca31a782b016e99/>.
epubgen_patches += 0002-Always-keep-page-properties-when-splitting-the-HTML-.patch.1
# Backport of <https://sourceforge.net/p/libepubgen/code/ci/1f602fcaa74fc9dbc6457019d11c602ff4040a4e/>.
epubgen_patches += 0003-Ensure-page-properties-in-the-page-span-works.patch.1
# Backport of <https://sourceforge.net/p/libepubgen/code/ci/aa254c9e6f2d1ecfa2512111746a77c05ba9717f/>
epubgen_patches += 0001-Enclose-span-with-ruby-if-text-ruby-text-is-set.patch.1
ifeq ($(COM_IS_CLANG),TRUE)
ifneq ($(filter -fsanitize=%,$(CC)),)
......
From 006848cb62225647c418d5143d4e88a9d73829da Mon Sep 17 00:00:00 2001
From: Miklos Vajna <vmiklos@collabora.co.uk>
Date: Fri, 22 Dec 2017 16:33:52 +0100
Subject: [PATCH] EPUBHTMLGenerator: avoid <div> inside <p> and/or <span>
This is not allowed in XHTML, but we wrote that markup when a text frame
was inside a span or a paragraph. The closest allowed markup in XHTML
seems to be closing the span/paragraph before opening the text box and
doing the opposite after the text box is closed.
---
src/lib/EPUBHTMLGenerator.cpp | 33 +++++++++++++++++++++++++++++++++
src/test/EPUBTextGeneratorTest.cpp | 4 +++-
2 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/src/lib/EPUBHTMLGenerator.cpp b/src/lib/EPUBHTMLGenerator.cpp
index 342213e..bc9c1b7 100644
--- a/src/lib/EPUBHTMLGenerator.cpp
+++ b/src/lib/EPUBHTMLGenerator.cpp
@@ -395,6 +395,8 @@ struct EPUBHTMLGeneratorImpl
, m_frameAnchorTypes()
, m_framePropertiesStack()
, m_linkPropertiesStack()
+ , m_paragraphAttributesStack()
+ , m_spanAttributesStack()
, m_stylesMethod(stylesMethod)
, m_layoutMethod(layoutMethod)
, m_actualSink()
@@ -495,6 +497,8 @@ struct EPUBHTMLGeneratorImpl
std::stack<RVNGPropertyList> m_framePropertiesStack;
/// This is used for links which don't have a href.
std::stack<RVNGPropertyList> m_linkPropertiesStack;
+ std::stack<RVNGPropertyList> m_paragraphAttributesStack;
+ std::stack<RVNGPropertyList> m_spanAttributesStack;
EPUBStylesMethod m_stylesMethod;
EPUBLayoutMethod m_layoutMethod;
@@ -683,6 +687,12 @@ void EPUBHTMLGenerator::openParagraph(const RVNGPropertyList &propList)
}
m_impl->output(false).openElement("p", attrs);
m_impl->m_hasText = false;
+
+ librevenge::RVNGPropertyList::Iter i(attrs);
+ RVNGPropertyList paragraphAttributes;
+ for (i.rewind(); i.next();)
+ paragraphAttributes.insert(i.key(), i()->clone());
+ m_impl->m_paragraphAttributesStack.push(paragraphAttributes);
}
void EPUBHTMLGenerator::closeParagraph()
@@ -690,6 +700,9 @@ void EPUBHTMLGenerator::closeParagraph()
if (m_impl->m_ignore)
return;
+ if (!m_impl->m_paragraphAttributesStack.empty())
+ m_impl->m_paragraphAttributesStack.pop();
+
if (!m_impl->m_hasText)
insertSpace();
@@ -717,12 +730,22 @@ void EPUBHTMLGenerator::openSpan(const RVNGPropertyList &propList)
break;
}
m_impl->output(false).openElement("span", attrs);
+
+ librevenge::RVNGPropertyList::Iter i(attrs);
+ RVNGPropertyList spanAttributes;
+ for (i.rewind(); i.next();)
+ spanAttributes.insert(i.key(), i()->clone());
+ m_impl->m_spanAttributesStack.push(spanAttributes);
}
void EPUBHTMLGenerator::closeSpan()
{
if (m_impl->m_ignore)
return;
+
+ if (!m_impl->m_spanAttributesStack.empty())
+ m_impl->m_spanAttributesStack.pop();
+
m_impl->output().closeElement("span");
}
@@ -931,6 +954,11 @@ void EPUBHTMLGenerator::openTextBox(const RVNGPropertyList & /*propList*/)
if (m_impl->m_ignore)
return;
+ if (!m_impl->m_spanAttributesStack.empty())
+ m_impl->output().closeElement("span");
+ if (!m_impl->m_paragraphAttributesStack.empty())
+ m_impl->output().closeElement("p");
+
RVNGPropertyList attrs;
if (!m_impl->m_framePropertiesStack.empty())
@@ -968,6 +996,11 @@ void EPUBHTMLGenerator::closeTextBox()
m_impl->output().insertEmptyElement("br", attrs);
}
}
+
+ if (!m_impl->m_paragraphAttributesStack.empty())
+ m_impl->output(false).openElement("p", m_impl->m_paragraphAttributesStack.top());
+ if (!m_impl->m_spanAttributesStack.empty())
+ m_impl->output(false).openElement("span", m_impl->m_spanAttributesStack.top());
}
void EPUBHTMLGenerator::openTable(const RVNGPropertyList &propList)
--
2.13.6
From a97e7f40bddba8e5d572b29811a19f34536190dc Mon Sep 17 00:00:00 2001
From: Miklos Vajna <vmiklos@collabora.co.uk>
Date: Fri, 22 Dec 2017 17:16:23 +0100
Subject: [PATCH] EPUBTableStyleManager: avoid vertical-align key without value
ERROR(CSS-008): test.epub/OEBPS/styles/stylesheet.css(1625,19): An error occurred while parsing the CSS: Token ';' not allowed here, expecting a property value.
---
src/lib/EPUBTableStyleManager.cpp | 5 +++--
src/test/EPUBTextGeneratorTest.cpp | 6 +++++-
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/src/lib/EPUBTableStyleManager.cpp b/src/lib/EPUBTableStyleManager.cpp
index a1ce33e..cf08737 100644
--- a/src/lib/EPUBTableStyleManager.cpp
+++ b/src/lib/EPUBTableStyleManager.cpp
@@ -255,8 +255,9 @@ void EPUBTableStyleManager::extractCellProperties(RVNGPropertyList const &pList,
else
cssProps["text-align"] = pList["fo:text-align"]->getStr().cstr();
}
- if (pList["style:vertical-align"])
- cssProps["vertical-align"] = pList["style:vertical-align"]->getStr().cstr();
+ const librevenge::RVNGProperty *verticalAlign = pList["style:vertical-align"];
+ if (verticalAlign && !verticalAlign->getStr().empty())
+ cssProps["vertical-align"] = verticalAlign->getStr().cstr();
else
cssProps["vertical-align"] = "top";
if (pList["fo:background-color"])
--
2.13.6
From 60baa7fb597cde57c3489d8b5066937e7edb779f Mon Sep 17 00:00:00 2001
From: Miklos Vajna <vmiklos@collabora.co.uk>
Date: Fri, 22 Dec 2017 17:39:31 +0100
Subject: [PATCH] EPUBHTMLGenerator: fix invalid XHTML with links at footnote
start
ERROR(RSC-005): test3.epub/OEBPS/sections/section0001.xhtml(2,568): Error while parsing file: The a element must not appear inside a elements.
---
src/lib/EPUBHTMLGenerator.cpp | 4 +++-
src/test/EPUBTextGeneratorTest.cpp | 9 +++++++++
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/src/lib/EPUBHTMLGenerator.cpp b/src/lib/EPUBHTMLGenerator.cpp
index bc9c1b7..59ded90 100644
--- a/src/lib/EPUBHTMLGenerator.cpp
+++ b/src/lib/EPUBHTMLGenerator.cpp
@@ -781,7 +781,9 @@ void EPUBHTMLGenerator::openLink(const RVNGPropertyList &propList)
m_impl->m_linkPropertiesStack.push(linkProperties);
}
else
- m_impl->output(false).openElement("a", attrs);
+ // Implicit sendDelayed=true, so that in case the link is at the start of a
+ // footnote, links are not nested.
+ m_impl->output().openElement("a", attrs);
}
void EPUBHTMLGenerator::closeLink()
--
2.13.6
From 51e17dc87d85f1dc71b380906f9260de4cd0371c Mon Sep 17 00:00:00 2001
From: Miklos Vajna <vmiklos@collabora.co.uk>
Date: Thu, 18 Jan 2018 14:54:06 +0100
Subject: [PATCH] EPUBImageManager: handle relative and absolute width
---
src/lib/EPUBImageManager.cpp | 6 +++++
src/test/EPUBTextGeneratorTest.cpp | 54 ++++++++++++++++++++++++++++++++++++++
2 files changed, 60 insertions(+)
diff --git a/src/lib/EPUBImageManager.cpp b/src/lib/EPUBImageManager.cpp
index bdf3bf0..cb4efee 100644
--- a/src/lib/EPUBImageManager.cpp
+++ b/src/lib/EPUBImageManager.cpp
@@ -171,6 +171,12 @@ void EPUBImageManager::extractImageProperties(librevenge::RVNGPropertyList const
continue;
cssProps[type[i]] = pList[field.c_str()]->getStr().cstr();
}
+
+ // Extract size.
+ if (auto pRelWidth = pList["style:rel-width"])
+ cssProps["width"] = pRelWidth->getStr().cstr();
+ else if (auto pWidth = pList["svg:width"])
+ cssProps["width"] = pWidth->getStr().cstr();
}
std::string EPUBImageManager::getWrapStyle(librevenge::RVNGPropertyList const &pList)
--
2.13.6
From c081609849b18113340c39a73b6af432a103a102 Mon Sep 17 00:00:00 2001
From: Miklos Vajna <vmiklos@collabora.co.uk>
Date: Mon, 22 Jan 2018 14:39:19 +0100
Subject: [PATCH] fixed layout: allow defining chapter names
Fixed layout normally just works with SVG images (one image / page), but
readable navigation document is still expected, e.g. PDF provides it. So
add a way to mention what chapters start on a given page.
---
src/lib/EPUBHTMLManager.cpp | 25 +++++++++++++++++++++++++
src/lib/EPUBHTMLManager.h | 3 +++
src/lib/EPUBPath.cpp | 11 +++++++++++
src/lib/EPUBPath.h | 4 ++++
src/lib/EPUBTextGenerator.cpp | 15 +++++++++++++++
src/test/EPUBTextGeneratorTest.cpp | 37 +++++++++++++++++++++++++++++++++++++
6 files changed, 95 insertions(+)
diff --git a/src/lib/EPUBHTMLManager.cpp b/src/lib/EPUBHTMLManager.cpp
index 5e96d1d..d35bc3f 100644
--- a/src/lib/EPUBHTMLManager.cpp
+++ b/src/lib/EPUBHTMLManager.cpp
@@ -93,6 +93,23 @@ void EPUBHTMLManager::writeTocTo(EPUBXMLSink &sink, const EPUBPath &tocPath, int
{
for (std::vector<EPUBPath>::size_type i = 0; m_paths.size() != i; ++i)
{
+ const std::vector<std::string> &chapters = m_paths[i].getChapters();
+ if (!chapters.empty())
+ {
+ for (const auto &chapter : chapters)
+ {
+ sink.openElement("li");
+ librevenge::RVNGPropertyList anchorAttrs;
+ anchorAttrs.insert("href", m_paths[i].relativeTo(tocPath).str().c_str());
+ sink.openElement("a", anchorAttrs);
+ std::ostringstream label;
+ sink.insertCharacters(chapter.c_str());
+ sink.closeElement("a");
+ sink.closeElement("li");
+ }
+ continue;
+ }
+
sink.openElement("li");
librevenge::RVNGPropertyList anchorAttrs;
anchorAttrs.insert("href", m_paths[i].relativeTo(tocPath).str().c_str());
@@ -140,6 +157,14 @@ void EPUBHTMLManager::insertHeadingText(const std::string &text)
m_paths.back().appendTitle(text);
}
+void EPUBHTMLManager::addChapterName(const std::string &text)
+{
+ if (m_paths.empty())
+ return;
+
+ m_paths.back().addChapter(text);
+}
+
bool EPUBHTMLManager::hasHeadingText() const
{
if (m_paths.empty())
diff --git a/src/lib/EPUBHTMLManager.h b/src/lib/EPUBHTMLManager.h
index 157896b..d48ddf2 100644
--- a/src/lib/EPUBHTMLManager.h
+++ b/src/lib/EPUBHTMLManager.h
@@ -51,6 +51,9 @@ public:
/// Appends text to the title of the current heading.
void insertHeadingText(const std::string &text);
+ /// Registers a chapter name for the current page (fixed layout case).
+ void addChapterName(const std::string &text);
+
/// If the current heading has a title.
bool hasHeadingText() const;
diff --git a/src/lib/EPUBPath.cpp b/src/lib/EPUBPath.cpp
index e1c05ed..be24de5 100644
--- a/src/lib/EPUBPath.cpp
+++ b/src/lib/EPUBPath.cpp
@@ -54,6 +54,7 @@ EPUBPath::Relative::Relative(const std::vector<std::string> &components)
EPUBPath::EPUBPath(const std::string &path)
: m_components()
, m_title()
+ , m_chapters()
{
const std::string trimmed(algorithm::trim_left_copy_if(path, algorithm::is_any_of("/")));
algorithm::split(m_components, trimmed, algorithm::is_any_of("/"), algorithm::token_compress_on);
@@ -116,6 +117,16 @@ void EPUBPath::appendTitle(const std::string &title)
m_title += title;
}
+void EPUBPath::addChapter(const std::string &chapter)
+{
+ m_chapters.push_back(chapter);
+}
+
+const std::vector<std::string> &EPUBPath::getChapters() const
+{
+ return m_chapters;
+}
+
std::string EPUBPath::getTitle() const
{
return m_title;
diff --git a/src/lib/EPUBPath.h b/src/lib/EPUBPath.h
index 12b8f25..76f2d7b 100644
--- a/src/lib/EPUBPath.h
+++ b/src/lib/EPUBPath.h
@@ -51,9 +51,13 @@ public:
void appendTitle(const std::string &title);
std::string getTitle() const;
+ /// Adds chapter name (fixed layout).
+ void addChapter(const std::string &chapter);
+ const std::vector<std::string> &getChapters() const;
private:
std::vector<std::string> m_components;
std::string m_title;
+ std::vector<std::string> m_chapters;
};
bool operator==(const EPUBPath &left, const EPUBPath &right);
diff --git a/src/lib/EPUBTextGenerator.cpp b/src/lib/EPUBTextGenerator.cpp
index 8e88adb..38ddcdf 100644
--- a/src/lib/EPUBTextGenerator.cpp
+++ b/src/lib/EPUBTextGenerator.cpp
@@ -270,7 +270,9 @@ void EPUBTextGenerator::openParagraph(const librevenge::RVNGPropertyList &propLi
{
const RVNGProperty *const breakBefore = propList["fo:break-before"];
if (isPageBreak(breakBefore) && m_impl->getSplitGuard().splitOnPageBreak())
+ {
m_impl->startNewHtmlFile();
+ }
const RVNGProperty *const breakAfter = propList["fo:break-after"];
m_impl->m_breakAfterPara = isPageBreak(breakAfter);
if (m_impl->getSplitGuard().splitOnSize())
@@ -282,6 +284,19 @@ void EPUBTextGenerator::openParagraph(const librevenge::RVNGPropertyList &propLi
m_impl->startNewHtmlFile();
m_impl->getSplitGuard().setCurrentHeadingLevel(outlineLevel ? outlineLevel->getInt() : 0);
+ if (const librevenge::RVNGPropertyListVector *chapterNames = m_impl->m_pageSpanProps.child("librevenge:chapter-names"))
+ {
+ for (unsigned long i = 0; i < chapterNames->count(); i++)
+ {
+ RVNGPropertyList const &chapter=(*chapterNames)[i];
+ const RVNGProperty *const chapterName = chapter["librevenge:name"];
+ if (!chapterName)
+ continue;
+
+ m_impl->getHtmlManager().addChapterName(chapterName->getStr().cstr());
+ }
+ }
+
m_impl->getSplitGuard().openLevel();
if (m_impl->m_inHeader || m_impl->m_inFooter)
--
2.13.6
From b6081f659e3000d9f3d5851278d8abdd33448353 Mon Sep 17 00:00:00 2001
From: Miklos Vajna <vmiklos@collabora.co.uk>
Date: Mon, 22 Jan 2018 15:54:43 +0100
Subject: [PATCH] fixed layout: avoid Page <N> entries when chapter names are
provided
---
src/lib/EPUBHTMLManager.cpp | 31 ++++++++++++++++++-------------
src/test/EPUBTextGeneratorTest.cpp | 16 ++++++++++++++++
2 files changed, 34 insertions(+), 13 deletions(-)
diff --git a/src/lib/EPUBHTMLManager.cpp b/src/lib/EPUBHTMLManager.cpp
index d35bc3f..35d82e8 100644
--- a/src/lib/EPUBHTMLManager.cpp
+++ b/src/lib/EPUBHTMLManager.cpp
@@ -7,6 +7,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
+#include <algorithm>
#include <cassert>
#include <iomanip>
#include <sstream>
@@ -91,24 +92,28 @@ void EPUBHTMLManager::writeTocTo(EPUBXMLSink &sink, const EPUBPath &tocPath, int
{
if (version >= 30)
{
+ bool hasChapterNames = std::find_if(m_paths.begin(), m_paths.end(), [](const EPUBPath &path)
+ {
+ return !path.getChapters().empty();
+ }) != m_paths.end();
for (std::vector<EPUBPath>::size_type i = 0; m_paths.size() != i; ++i)
{
const std::vector<std::string> &chapters = m_paths[i].getChapters();
- if (!chapters.empty())
+ for (const auto &chapter : chapters)
{
- for (const auto &chapter : chapters)
- {
- sink.openElement("li");
- librevenge::RVNGPropertyList anchorAttrs;
- anchorAttrs.insert("href", m_paths[i].relativeTo(tocPath).str().c_str());
- sink.openElement("a", anchorAttrs);
- std::ostringstream label;
- sink.insertCharacters(chapter.c_str());
- sink.closeElement("a");
- sink.closeElement("li");
- }
- continue;
+ sink.openElement("li");
+ librevenge::RVNGPropertyList anchorAttrs;
+ anchorAttrs.insert("href", m_paths[i].relativeTo(tocPath).str().c_str());
+ sink.openElement("a", anchorAttrs);
+ std::ostringstream label;
+ sink.insertCharacters(chapter.c_str());
+ sink.closeElement("a");
+ sink.closeElement("li");
}
+ if (hasChapterNames)
+ // Chapter names are provided for this document, so never write Page
+ // <N> entries.
+ continue;
sink.openElement("li");
librevenge::RVNGPropertyList anchorAttrs;
--
2.13.6
......@@ -428,10 +428,10 @@
"dest-filename": "external/tarballs/ReemKufi-0.7.zip"
},
{
"url": "https://dev-www.libreoffice.org/src/libepubgen-0.1.0.tar.bz2",
"sha256": "730bd1cbeee166334faadbc06c953a67b145c3c4754a3b503482066dae4cd633",
"url": "https://dev-www.libreoffice.org/src/libepubgen-0.1.1.tar.xz",
"sha256": "03e084b994cbeffc8c3dd13303b2cb805f44d8f2c3b79f7690d7e3fc7f6215ad",
"type": "file",
"dest-filename": "external/tarballs/libepubgen-0.1.0.tar.bz2"
"dest-filename": "external/tarballs/libepubgen-0.1.1.tar.xz"
},
{
"url": "https://dev-www.libreoffice.org/src/libqxp-0.0.1.tar.xz",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment