/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* This file is part of the libepubgen project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <cassert>
#include <iomanip>
#include <sstream>
#include "EPUBHTMLManager.h"
#include "EPUBManifest.h"
#include "EPUBGenerator.h"
namespace libepubgen
{
namespace
{
/// Extracts a title string from a path and provides a fallback if it would be empty.
void getPathTitle(std::ostringstream &label, const EPUBPath &path, EPUBLayoutMethod layout, std::vector<EPUBPath>::size_type index)
{
if (path.getTitle().empty())
{
if (layout == EPUB_LAYOUT_METHOD_FIXED)
label << "Page ";
else
label << "Section ";
label << (index + 1);
}
else
label << path.getTitle();
}
}
EPUBHTMLManager::EPUBHTMLManager(EPUBManifest &manifest)
: m_manifest(manifest)
, m_paths()
, m_contents()
, m_ids()
, m_number()
{
}
const EPUBHTMLGeneratorPtr_t EPUBHTMLManager::create(EPUBImageManager &imageManager, EPUBFontManager &fontManager, EPUBListStyleManager &listStyleManager, EPUBParagraphStyleManager ¶graphStyleManager, EPUBSpanStyleManager &spanStyleManager, EPUBTableStyleManager &tableStyleManager, const EPUBPath &stylesheetPath, EPUBStylesMethod stylesMethod, EPUBLayoutMethod layoutMethod, int version)
{
std::ostringstream nameBuf;
nameBuf << "section" << std::setw(4) << std::setfill('0') << m_number.next();
m_ids.push_back(nameBuf.str());
nameBuf << ".xhtml";
m_paths.push_back(EPUBPath("OEBPS/sections") / nameBuf.str());
m_manifest.insert(m_paths.back(), "application/xhtml+xml", m_ids.back(), "");
m_contents.push_back(EPUBXMLSink());
const EPUBHTMLGeneratorPtr_t gen(
new EPUBHTMLGenerator(m_contents.back(), imageManager, fontManager, listStyleManager, paragraphStyleManager, spanStyleManager, tableStyleManager, m_paths.back(), stylesheetPath, stylesMethod, layoutMethod, version));
return gen;
}
void EPUBHTMLManager::writeTo(EPUBPackage &package)
{
assert(m_contents.size() == m_paths.size());
std::vector<EPUBPath>::const_iterator pathIt = m_paths.begin();
auto contentIt = m_contents.begin();
for (; (m_paths.end() != pathIt) && (m_contents.end() != contentIt); ++pathIt, ++contentIt)
contentIt->writeTo(package, pathIt->str().c_str());
}
void EPUBHTMLManager::writeSpineTo(EPUBXMLSink &sink)
{
for (std::vector<std::string>::const_iterator it = m_ids.begin(); m_ids.end() != it; ++it)
{
librevenge::RVNGPropertyList itemrefAttrs;
itemrefAttrs.insert("idref", it->c_str());
sink.insertEmptyElement("itemref", itemrefAttrs);
}
}
void EPUBHTMLManager::writeTocTo(EPUBXMLSink &sink, const EPUBPath &tocPath, int version, EPUBLayoutMethod layout)
{
if (version >= 30)
{
for (std::vector<EPUBPath>::size_type i = 0; m_paths.size() != i; ++i)
{
sink.openElement("li");
librevenge::RVNGPropertyList anchorAttrs;
anchorAttrs.insert("href", m_paths[i].relativeTo(tocPath).str().c_str());
sink.openElement("a", anchorAttrs);
std::ostringstream label;
getPathTitle(label, m_paths[i], layout, i);
sink.insertCharacters(label.str().c_str());
sink.closeElement("a");
sink.closeElement("li");
}
return;
}
librevenge::RVNGPropertyList navPointAttrs;
for (std::vector<EPUBPath>::size_type i = 0; m_paths.size() != i; ++i)
{
std::ostringstream id;
id << "section" << (i + 1);
navPointAttrs.insert("id", id.str().c_str());
navPointAttrs.insert("class", "document");
std::ostringstream playOrder;
playOrder << (i + 1);
navPointAttrs.insert("playOrder", playOrder.str().c_str());
sink.openElement("navPoint", navPointAttrs);
sink.openElement("navLabel");
sink.openElement("text");
std::ostringstream label;
getPathTitle(label, m_paths[i], layout, i);
sink.insertCharacters(label.str().c_str());
sink.closeElement("text");
sink.closeElement("navLabel");
librevenge::RVNGPropertyList contentAttrs;
contentAttrs.insert("src", m_paths[i].relativeTo(tocPath).str().c_str());
sink.insertEmptyElement("content", contentAttrs);
sink.closeElement("navPoint");
}
}
void EPUBHTMLManager::insertHeadingText(const std::string &text)
{
if (m_paths.empty())
return;
m_paths.back().appendTitle(text);
}
bool EPUBHTMLManager::hasHeadingText() const
{
if (m_paths.empty())
return false;
return !m_paths.back().getTitle().empty();
}
}
/* vim:set shiftwidth=2 softtabstop=2 expandtab: */