From 6b3ac2e1b0e3b2cefb8511166ba70bedebecbf1b Mon Sep 17 00:00:00 2001 From: Jaydeep Solanki Date: Tue, 22 Oct 2013 05:33:17 +0530 Subject: [PATCH] fix internal links --- generators/epub/converter.cpp | 69 ++++++++++++++++++++++++++++------- generators/epub/converter.h | 3 +- 2 files changed, 57 insertions(+), 15 deletions(-) diff --git a/generators/epub/converter.cpp b/generators/epub/converter.cpp index 353d32586..32b28b541 100644 --- a/generators/epub/converter.cpp +++ b/generators/epub/converter.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -62,9 +63,10 @@ void Converter::_emitData(Okular::DocumentInfo::Key key, } } -// Got over the blocks from start and add them to hashes use name as the +// Got over the blocks from start and add them to hashes use name as the // prefix for local links void Converter::_handle_anchors(const QTextBlock &start, const QString &name) { + const QString curDir = QFileInfo(name).path(); for (QTextBlock bit = start; bit != mTextDocument->end(); bit = bit.next()) { for (QTextBlock::iterator fit = bit.begin(); !(fit.atEnd()); ++fit) { @@ -72,14 +74,35 @@ void Converter::_handle_anchors(const QTextBlock &start, const QString &name) { QTextFragment frag = fit.fragment(); if (frag.isValid() && frag.charFormat().isAnchor()) { - QUrl href(frag.charFormat().anchorHref()); + QString hrefString = frag.charFormat().anchorHref(); + // remove ./ or ../ + // making it easier to compare, with links + while(!hrefString.isNull() && ( hrefString.at(0) == '.' || hrefString.at(0) == '/') ){ + hrefString.remove(0,1); + } + + QUrl href(hrefString); if (href.isValid() && !href.isEmpty()) { if (href.isRelative()) { // Inside document link - mLocalLinks.insert(href.toString(), - QPair(frag.position(), - frag.position()+frag.length())); - } else { // Outside document link + if(!hrefString.indexOf('#')) + hrefString = name + hrefString; + else if(QFileInfo(hrefString).path() == "." && curDir != ".") + hrefString = curDir + '/' + hrefString; + + // QTextCharFormat sometimes splits a link in two + // if there's no white space between words & the first one is an anchor + // consider whole word to be an anchor + ++fit; + int fragLen = frag.length(); + if(!fit.atEnd() && ((fit.fragment().position() - frag.position()) == 1)) + fragLen += fit.fragment().length(); + --fit; + + _insert_local_links(hrefString, + QPair(frag.position(), + frag.position()+fragLen)); + } else { // Outside document link Okular::BrowseAction *action = new Okular::BrowseAction(href.toString()); @@ -101,6 +124,17 @@ void Converter::_handle_anchors(const QTextBlock &start, const QString &name) { } } +void Converter::_insert_local_links(const QString &key, const QPair &value) +{ + if(mLocalLinks.contains(key)){ + mLocalLinks[key].append(value); + } else { + QVector< QPair > vec; + vec.append(value); + mLocalLinks.insert(key,vec); + } +} + QTextDocument* Converter::convert( const QString &fileName ) { EpubDocument *newDocument = new EpubDocument(fileName); @@ -142,6 +176,10 @@ QTextDocument* Converter::convert( const QString &fileName ) mTextDocument->setCurrentSubDocument(link); QString htmlContent = QString::fromUtf8(epub_it_get_curr(it)); + // as QTextCharFormat::anchorNames() ignores sections, replace it with

+ htmlContent.replace(QRegExp("< *section")," > hit(mLocalLinks); + QHashIterator > > hit(mLocalLinks); while (hit.hasNext()) { hit.next(); const QTextBlock block = mSectionMap.value(hit.key()); - if (block.isValid()) { // be sure we actually got a block - Okular::DocumentViewport viewport = - calculateViewport(mTextDocument, block); - Okular::GotoAction *action = new Okular::GotoAction(QString(), viewport); + for (int i = 0; i < hit.value().size(); ++i) { + if (block.isValid()) { // be sure we actually got a block + Okular::DocumentViewport viewport = + calculateViewport(mTextDocument, block); + + Okular::GotoAction *action = new Okular::GotoAction(QString(), viewport); - emit addAction(action, hit.value().first, hit.value().second); - } else { - kDebug() << "Error: no block found for "<< hit.key(); + emit addAction(action, hit.value()[i].first, hit.value()[i].second); + } else { + kDebug() << "Error: no block found for "<< hit.key(); + } } } diff --git a/generators/epub/converter.h b/generators/epub/converter.h index 969dc9f8e..d368c70e3 100644 --- a/generators/epub/converter.h +++ b/generators/epub/converter.h @@ -30,10 +30,11 @@ namespace Epub { void _emitData(Okular::DocumentInfo::Key key, enum epub_metadata type); void _handle_anchors(const QTextBlock &start, const QString &name); + void _insert_local_links(const QString &key, const QPair &value); EpubDocument *mTextDocument; QHash mSectionMap; - QHash > mLocalLinks; + QHash > > mLocalLinks; }; }