void ReadiumJSApi::digInto(const NavigationList& list, TOCEntry& rOut) { std::string sBaseUrl = getBasePath(); // fast fix int iTrimLen = sBaseUrl.length(); for (NavigationList::const_iterator v = list.begin(); v != list.end(); ++v) { NavigationPoint* pt = dynamic_cast<NavigationPoint*>(v->get()); std::string sTitle = pt->Title().c_str(); std::string sPath = pt->AbsolutePath(pkg).c_str(); if (0 == sPath.find(sBaseUrl)) { sPath = sPath.substr(iTrimLen, sPath.length()); } rOut.arrChildren.push_back(TOCEntry(sTitle, sPath)); const NavigationList& list = pt->Children(); digInto(list, (rOut.arrChildren.back()) ); } }
NavigationList PackageBase::NavTablesFromManifestItem(shared_ptr<PackageBase> owner, shared_ptr<ManifestItem> pItem) { PackagePtr sharedPkg = std::dynamic_pointer_cast<Package>(owner); if ( !sharedPkg ) return NavigationList(); if ( pItem == nullptr ) return NavigationList(); xmlDocPtr doc = pItem->ReferencedDocument(); if ( doc == nullptr ) return NavigationList(); // find each <nav> node #if EPUB_COMPILER_SUPPORTS(CXX_INITIALIZER_LISTS) XPathWrangler xpath(doc, {{"epub", ePub3NamespaceURI}}); // goddamn I love C++11 initializer list constructors #else XPathWrangler::NamespaceList __m; __m["epub"] = ePub3NamespaceURI; XPathWrangler xpath(doc, __m); #endif xpath.NameDefaultNamespace("html"); xmlNodeSetPtr nodes = xpath.Nodes("//html:nav"); NavigationList tables; for ( int i = 0; i < nodes->nodeNr; i++ ) { xmlNodePtr navNode = nodes->nodeTab[i]; auto navTablePtr = std::make_shared<class NavigationTable>(sharedPkg, pItem->Href()); if ( navTablePtr->ParseXML(navNode) ) tables.push_back(navTablePtr); } xmlXPathFreeNodeSet(nodes); // now look for any <dl> nodes with an epub:type of "glossary" nodes = xpath.Nodes("//html:dl[epub:type='glossary']"); return tables; }
void PackageBase::InstallPrefixesFromAttributeValue(const ePub3::string &attrValue) { if ( attrValue.empty() ) return; static std::regex re(R"X((\w+):\s*(.+?)(?:\s+|$))X", std::regex::ECMAScript|std::regex::optimize); auto pos = std::sregex_iterator(attrValue.stl_str().begin(), attrValue.stl_str().end(), re); auto end = std::sregex_iterator(); while ( pos != end ) { if ( pos->size() == 3 ) // entire match plus two captures { RegisterPrefixIRIStem(pos->str(1), pos->str(2)); } ++pos; } } const SpineItem* PackageBase::ConfirmOrCorrectSpineItemQualifier(const SpineItem* pItem, CFI::Component *pComponent) const { if ( pComponent->HasQualifier() && pItem->Idref() != pComponent->qualifier ) { // find the item with the qualifier pItem = _spine.get(); uint32_t idx = 2; while ( pItem != nullptr ) { if ( pItem->Idref() == pComponent->qualifier ) { // found it-- correct the CFI pComponent->nodeIndex = idx; break; } pItem = pItem->Next(); } } return pItem; } NavigationList PackageBase::NavTablesFromManifestItem(const ManifestItem* pItem) { if ( pItem == nullptr ) return NavigationList(); xmlDocPtr doc = pItem->ReferencedDocument(); if ( doc == nullptr ) return NavigationList(); // find each <nav> node XPathWrangler xpath(doc, {{"epub", ePub3NamespaceURI}}); // goddamn I love C++11 initializer list constructors xpath.NameDefaultNamespace("html"); xmlNodeSetPtr nodes = xpath.Nodes("//html:nav"); NavigationList tables; for ( size_t i = 0; i < nodes->nodeNr; i++ ) { xmlNodePtr navNode = nodes->nodeTab[i]; tables.push_back(new class NavigationTable(navNode)); } xmlXPathFreeNodeSet(nodes); // now look for any <dl> nodes with an epub:type of "glossary" nodes = xpath.Nodes("//html:dl[epub:type='glossary']"); return tables; }