diff options
author | xiota | 2023-10-29 09:14:57 -0700 |
---|---|---|
committer | xiota | 2023-10-29 09:15:19 -0700 |
commit | 0ec92f44085bbe4cec12d750fd1b6168d363c573 (patch) | |
tree | 73247916ecfd634a49a7be686dac08f3b83fb023 | |
parent | bca61c1bd9e6ae02d7ae493996d131c570a2f3fb (diff) | |
download | aur-0ec92f44085bbe4cec12d750fd1b6168d363c573.tar.gz |
2.0.2.r11: update patches
-rw-r--r-- | .SRCINFO | 14 | ||||
-rw-r--r-- | 0001-modify-default-navigation-css.patch | 60 | ||||
-rw-r--r-- | 0002-skip-epub-version-check.patch | 1706 | ||||
-rw-r--r-- | 0003-don-t-write-version-and-modified-tags.patch | 108 | ||||
-rw-r--r-- | PKGBUILD | 14 | ||||
-rw-r--r-- | default_nav_css.patch | 21 | ||||
-rw-r--r-- | skip_epub_version_check.patch | 27 | ||||
-rw-r--r-- | skip_version_mod_tags.patch | 70 |
8 files changed, 1888 insertions, 132 deletions
@@ -1,6 +1,6 @@ pkgbase = sigil-git pkgdesc = multi-platform EPUB2/EPUB3 ebook editor - pkgver = 2.0.2.r6.gd223713e5 + pkgver = 2.0.2.r11.gb9438a876 pkgrel = 1 url = https://github.com/Sigil-Ebook/Sigil arch = x86_64 @@ -36,12 +36,12 @@ pkgbase = sigil-git conflicts = sigil options = !debug source = sigil::git+https://github.com/Sigil-Ebook/Sigil.git - source = default_nav_css.patch - source = skip_epub_version_check.patch - source = skip_version_mod_tags.patch + source = 0001-modify-default-navigation-css.patch + source = 0002-skip-epub-version-check.patch + source = 0003-don-t-write-version-and-modified-tags.patch sha256sums = SKIP - sha256sums = 3478ff361a34fd7cd7811d5103cbace91ecc790463684aaab9e21687b5553a28 - sha256sums = fc2bdc23d13b2e917f08608b516495b744f991642f73c1f6d943cf322a25fc11 - sha256sums = c74be3af315c9ffe181df6b465d0037f152f6078b953e6eeaab7b2932ae4c729 + sha256sums = c01f2028fd2a77fa48ddeefc70b780d185131f81c8c3b3f4f3bfd670cd1d574f + sha256sums = d06138d38a2d29ca020ec575bd2aa975df48cf61bbad975140fe5f304e23f6b0 + sha256sums = 4bddaaf8666e3d060ba51989c94d6c3a2c23a5b037dd69abe6c61af51b580720 pkgname = sigil-git diff --git a/0001-modify-default-navigation-css.patch b/0001-modify-default-navigation-css.patch new file mode 100644 index 000000000000..11332b2cbcee --- /dev/null +++ b/0001-modify-default-navigation-css.patch @@ -0,0 +1,60 @@ +From 949f7e50053057b9443cfabef77f048f86301501 Mon Sep 17 00:00:00 2001 +From: xiota +Date: Sun, 29 Oct 2023 03:50:46 -0700 +Subject: [PATCH 1/3] modify default navigation css + +--- + src/BookManipulation/Book.cpp | 10 ++++++++++ + src/BookManipulation/Book.cpp.rej | 19 +++++++++++++++++++ + 2 files changed, 29 insertions(+) + create mode 100644 src/BookManipulation/Book.cpp.rej + +diff --git a/src/BookManipulation/Book.cpp b/src/BookManipulation/Book.cpp +index e8beaff..38344de 100644 +--- a/src/BookManipulation/Book.cpp ++++ b/src/BookManipulation/Book.cpp +@@ -129,6 +129,16 @@ static const QString SGC_NAV_CSS_FILE = + "}\n\n" + "ol {\n" + " list-style-type: none;\n" ++ " padding-left: 1.5rem;\n" ++ "}\n\n" ++ "li > ol {\n" ++ " margin-bottom: 0.75rem;\n" ++ "}\n\n" ++ "li {\n" ++ " margin-top: 0.25rem;\n" ++ "}\n\n" ++ "a {\n" ++ " text-decoration: none;\n" + "}\n\n"; + + +diff --git a/src/BookManipulation/Book.cpp.rej b/src/BookManipulation/Book.cpp.rej +new file mode 100644 +index 0000000..c14cd6f +--- /dev/null ++++ b/src/BookManipulation/Book.cpp.rej +@@ -0,0 +1,19 @@ ++--- src/BookManipulation/Book.cpp +++++ src/BookManipulation/Book.cpp ++@@ -126,6 +126,16 @@ ++ "}\n\n" ++ "ol {\n" ++ " list-style-type: none;\n" +++ " padding-left: 1.5rem;\n" +++ "}\n\n" +++ "li > ol {\n" +++ " margin-bottom: 0.75rem;\n" +++ "}\n\n" +++ "li {\n" +++ " margin-top: 0.25rem;\n" +++ "}\n\n" +++ "a {\n" +++ " text-decoration: none;\n" ++ "}\n\n"; ++ ++ +-- +2.42.0 + diff --git a/0002-skip-epub-version-check.patch b/0002-skip-epub-version-check.patch new file mode 100644 index 000000000000..9cb5694f9e44 --- /dev/null +++ b/0002-skip-epub-version-check.patch @@ -0,0 +1,1706 @@ +From d13cbc01b92a3a16411823359741b3723376b17b Mon Sep 17 00:00:00 2001 +From: xiota +Date: Sun, 29 Oct 2023 03:51:25 -0700 +Subject: [PATCH 2/3] skip epub version check + +Allows changing from epub2 to epub3 by directly editing +the opf. Some data is lost and needs to be recreated +(eg, table of contents). +--- + src/ResourceObjects/OPFResource.cpp | 14 - + src/ResourceObjects/OPFResource.cpp.orig | 1658 ++++++++++++++++++++++ + 2 files changed, 1658 insertions(+), 14 deletions(-) + create mode 100644 src/ResourceObjects/OPFResource.cpp.orig + +diff --git a/src/ResourceObjects/OPFResource.cpp b/src/ResourceObjects/OPFResource.cpp +index 4b7668d..7f7020b 100644 +--- a/src/ResourceObjects/OPFResource.cpp ++++ b/src/ResourceObjects/OPFResource.cpp +@@ -1493,20 +1493,6 @@ void OPFResource::UpdateText(const OPFParser &p) + QString OPFResource::ValidatePackageVersion(const QString& source) + { + QString newsource = source; +- QString orig_version = GetEpubVersion(); +- QRegularExpression pkgversion_search(PKG_VERSION, QRegularExpression::CaseInsensitiveOption); +- QRegularExpressionMatch mo = pkgversion_search.match(newsource); +- if (mo.hasMatch()) { +- QString version = mo.captured(1); +- if (version != orig_version) { +- newsource.replace(mo.capturedStart(1), mo.capturedLength(1), orig_version); +- if (!m_WarnedAboutVersion && !version.startsWith('1')) { +- Utility::DisplayStdWarningDialog("Changing package version inside Sigil is not supported", +- "Use an appropriate output plugin to make the initial conversion"); +- m_WarnedAboutVersion = true; +- } +- } +- } + return newsource; + } + +diff --git a/src/ResourceObjects/OPFResource.cpp.orig b/src/ResourceObjects/OPFResource.cpp.orig +new file mode 100644 +index 0000000..4b7668d +--- /dev/null ++++ b/src/ResourceObjects/OPFResource.cpp.orig +@@ -0,0 +1,1658 @@ ++/************************************************************************ ++** ++** Copyright (C) 2015-2023 Kevin B. Hendricks Stratford, ON Canada ++** Copyright (C) 2013 John Schember <john@nachtimwald.com> ++** Copyright (C) 2009-2011 Strahinja Markovic <strahinja.markovic@gmail.com> ++** ++** This file is part of Sigil. ++** ++** Sigil is free software: you can redistribute it and/or modify ++** it under the terms of the GNU General Public License as published by ++** the Free Software Foundation, either version 3 of the License, or ++** (at your option) any later version. ++** ++** Sigil is distributed in the hope that it will be useful, ++** but WITHOUT ANY WARRANTY; without even the implied warranty of ++** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++** GNU General Public License for more details. ++** ++** You should have received a copy of the GNU General Public License ++** along with Sigil. If not, see <http://www.gnu.org/licenses/>. ++** ++*************************************************************************/ ++ ++#include <memory> ++ ++#include <QtCore/QBuffer> ++#include <QtCore/QDate> ++#include <QtCore/QDir> ++#include <QtCore/QFileInfo> ++#include <QtCore/QUuid> ++#include <QRegularExpression> ++#include <QRegularExpressionMatch> ++#include <QDateTime> ++#include <QDebug> ++ ++#include "BookManipulation/CleanSource.h" ++#include "BookManipulation/XhtmlDoc.h" ++#include "BookManipulation/FolderKeeper.h" ++#include "Misc/Utility.h" ++#include "Misc/SettingsStore.h" ++#include "Misc/GuideItems.h" ++#include "Misc/Landmarks.h" ++#include "Misc/MediaTypes.h" ++#include "ResourceObjects/HTMLResource.h" ++#include "ResourceObjects/ImageResource.h" ++#include "ResourceObjects/NCXResource.h" ++#include "ResourceObjects/OPFResource.h" ++#include "ResourceObjects/NavProcessor.h" ++#include "sigil_constants.h" ++#include "sigil_exception.h" ++ ++#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) ++ #define QT_ENUM_SKIPEMPTYPARTS Qt::SkipEmptyParts ++ #define QT_ENUM_KEEPEMPTYPARTS Qt::KeepEmptyParts ++#else ++ #define QT_ENUM_SKIPEMPTYPARTS QString::SkipEmptyParts ++ #define QT_ENUM_KEEPEMPTYPARTS QString::KeepEmptyParts ++#endif ++ ++static const QString SIGIL_VERSION_META_NAME = "Sigil version"; ++static const QString OPF_XML_NAMESPACE = "http://www.idpf.org/2007/opf"; ++static const QString FALLBACK_MIMETYPE = "text/plain"; ++static const QString ITEM_ELEMENT_TEMPLATE = "<item id=\"%1\" href=\"%2\" media-type=\"%3\"/>"; ++static const QString ITEMREF_ELEMENT_TEMPLATE = "<itemref idref=\"%1\"/>"; ++static const QString OPF_REWRITTEN_COMMENT = "<!-- Your OPF file was broken so Sigil " ++ "tried to rebuild it for you. -->"; ++ ++static const QString PKG_VERSION = "<\\s*package[^>]*version\\s*=\\s*[\"\']([^\'\"]*)[\'\"][^>]*>"; ++ ++static const QString TEMPLATE_TEXT = ++ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ++ "<package version=\"2.0\" xmlns=\"http://www.idpf.org/2007/opf\" unique-identifier=\"BookId\">\n\n" ++ " <metadata xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:opf=\"http://www.idpf.org/2007/opf\">\n" ++ " <dc:identifier opf:scheme=\"UUID\" id=\"BookId\">urn:uuid:%1</dc:identifier>\n" ++ " <dc:language>%2</dc:language>\n" ++ " <dc:title>%3</dc:title>\n" ++ " </metadata>\n\n" ++ " <manifest>\n" ++ " </manifest>\n\n" ++ " <spine>\n" ++ " </spine>\n\n" ++ "</package>"; ++ ++/** ++ ** Epub 3 reserved prefix values for the package tag. ++ ** See http://www.idpf.org/epub/vocab/package/pfx/ ++ ** ++ ** Prefix IRI ++ ** --------- --------------------------------------------------------- ++ ** dcterms http://purl.org/dc/terms/ ++ ** epubsc http://idpf.org/epub/vocab/sc/# ++ ** marc http://id.loc.gov/vocabulary/ ++ ** media http://www.idpf.org/epub/vocab/overlays/# ++ ** onix http://www.editeur.org/ONIX/book/codelists/current.html# ++ ** rendition http://www.idpf.org/vocab/rendition/# ++ ** schema http://schema.org/ ++ ** xsd http://www.w3.org/2001/XMLSchema# ++ ** ++ ** ++ ** Note single space is required after ":" that delimits the prefix ++ ** ++ ** example: ++ ** ++ ** <package … ++ ** prefix="foaf: http://xmlns.com/foaf/spec/ ++ ** dbp: http://dbpedia.org/ontology/"> ++ ** ++ */ ++ ++// " <item id=\"nav\" href=\"Text/nav.xhtml\" media-type=\"application/xhtml+xml\" properties=\"nav\"/>\n" ++// " <itemref idref=\"nav\" linear=\"no\" />\n" ++ ++ ++static const QString TEMPLATE3_TEXT = ++ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ++ "<package version=\"3.0\" unique-identifier=\"BookId\" xmlns=\"http://www.idpf.org/2007/opf\">\n\n" ++ " <metadata xmlns:dc=\"http://purl.org/dc/elements/1.1/\">\n" ++ " <dc:identifier id=\"BookId\">urn:uuid:%1</dc:identifier>\n" ++ " <dc:language>%2</dc:language>\n" ++ " <dc:title>%3</dc:title>\n" ++ " <meta property=\"dcterms:modified\">%4</meta>\n" ++ " </metadata>\n\n" ++ " <manifest>\n" ++ " </manifest>\n\n" ++ " <spine>\n" ++ " </spine>\n\n" ++ "</package>"; ++ ++ ++OPFResource::OPFResource(const QString &mainfolder, ++ const QString &fullfilepath, ++ const QString &version, ++ QObject *parent) ++ : XMLResource(mainfolder, fullfilepath, parent), ++ m_NavResource(NULL), ++ m_WarnedAboutVersion(false) ++{ ++ FillWithDefaultText(version); ++ // Make sure the file exists on disk. ++ // Among many reasons, this also solves the problem ++ // with the Book Browser not displaying an icon for this resource. ++ SaveToDisk(); ++} ++ ++ ++// just renaming the opf (but not moving it) should not trigger ++// a need for other source updates ++// but we will need to rewrite the META-INF/container.xml ++bool OPFResource::RenameTo(const QString &new_filename) ++{ ++ bool successful = Resource::RenameTo(new_filename); ++ if (successful) { ++ FolderKeeper::UpdateContainerXML(GetFullPathToBookFolder(), GetRelativePath()); ++ } ++ return successful; ++} ++ ++ ++// moving the opf should trigger a need for many source updates ++// and the need to rewrite the META-INF/container.xml ++bool OPFResource::MoveTo(const QString &newbookpath) ++{ ++ bool successful = Resource::MoveTo(newbookpath); ++ if (successful) { ++ FolderKeeper::UpdateContainerXML(GetFullPathToBookFolder(), GetRelativePath()); ++ } ++ return successful; ++} ++ ++ ++Resource::ResourceType OPFResource::Type() const ++{ ++ return Resource::OPFResourceType; ++} ++ ++ ++QString OPFResource::GetText() const ++{ ++ return TextResource::GetText(); ++} ++ ++ ++void OPFResource::SetText(const QString &text) ++{ ++ emit TextChanging(); ++ QWriteLocker locker(&GetLock()); ++ QString source = ValidatePackageVersion(text); ++ TextResource::SetText(source); ++} ++ ++ ++bool OPFResource::LoadFromDisk() ++{ ++ try { ++ const QString &text = Utility::ReadUnicodeTextFile(GetFullPath()); ++ SetText(text); ++ emit LoadedFromDisk(); ++ return true; ++ } catch (CannotOpenFile&) { ++ // ++ } ++ return false; ++} ++ ++QList<Resource*> OPFResource::GetSpineOrderResources( const QList<Resource *> &resources) ++{ ++ QReadLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ const QHash<QString, Resource*> id_mapping = GetManifestIDResourceMapping(resources, p); ++ QList<Resource *> spine_order; ++ for (int i = 0; i < p.m_spine.count(); ++i) { ++ QString idref = p.m_spine.at(i).m_idref; ++ if (id_mapping.contains(idref)) { ++ spine_order << id_mapping[idref]; ++ } ++ } ++ return spine_order; ++} ++ ++QHash <Resource *, int> OPFResource::GetReadingOrderAll( const QList <Resource *> resources) ++{ ++ QReadLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ QHash <Resource *, int> reading_order; ++ QHash<QString, int> id_order; ++ for (int i = 0; i < p.m_spine.count(); ++i) { ++ id_order[p.m_spine.at(i).m_idref] = i; ++ } ++ QHash<Resource *, QString> id_mapping = GetResourceManifestIDMapping(resources, p); ++ foreach(Resource *resource, resources) { ++ reading_order[resource] = id_order[id_mapping[resource]]; ++ } ++ return reading_order; ++} ++ ++ ++int OPFResource::GetReadingOrder(const HTMLResource *html_resource) const ++{ ++ QReadLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ const Resource *resource = static_cast<const Resource *>(html_resource); ++ QString resource_id = GetResourceManifestID(resource, p); ++ for (int i = 0; i < p.m_spine.count(); ++i) { ++ QString idref = p.m_spine.at(i).m_idref; ++ if (resource_id == idref) { ++ return i; ++ } ++ } ++ return -1; ++} ++ ++void OPFResource::MoveReadingOrder(const HTMLResource* from_resource, const HTMLResource* after_resource) ++{ ++ QWriteLocker locker(&GetLock()); ++ const Resource *from_res = static_cast<const Resource *>(from_resource); ++ const Resource *after_res = static_cast<const Resource *>(after_resource); ++ if (from_res == NULL || after_res == NULL) return; ++ ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ QString from_id = GetResourceManifestID(from_res, p); ++ QString after_id = GetResourceManifestID(after_res, p); ++ ++ int from_pos = -1; ++ int after_pos = -1; ++ int spine_count = p.m_spine.count(); ++ for (int i = 0; i < spine_count; i++) { ++ QString aref = p.m_spine.at(i).m_idref; ++ if (aref == from_id) from_pos = i; ++ if (aref == after_id) after_pos = i; ++ } ++ ++ if ((from_pos < 0) || (after_pos < 0)) return; ++ if (from_pos >= spine_count || after_pos >= spine_count) return; ++ // a move is equivalent to the sequence insert(after, takeAt(from)) ++ // if takeAt pos < after pos, it effectively increases the after position by one ++ // if takeAt pos > after pos, you need to increment after pos by 1 ++ if (from_pos != after_pos + 1) { ++ if (from_pos > after_pos) after_pos += 1; ++ p.m_spine.move(from_pos, after_pos); ++ } ++ UpdateText(p); ++} ++ ++ ++QString OPFResource::GetMainIdentifierValue() const ++{ ++ QReadLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ int i = GetMainIdentifier(p); ++ if (i > -1) { ++ return QString(p.m_metadata.at(i).m_content); ++ } ++ return QString(); ++} ++ ++void OPFResource::SaveToDisk(bool book_wide_save) ++{ ++ QString source = ValidatePackageVersion(CleanSource::ProcessXML(GetText(),"application/oebps-package+xml")); ++ // Work around for covers appearing on the Nook. Issue 942. ++ source = source.replace(QRegularExpression("<meta content=\"([^\"]+)\" name=\"cover\""), "<meta name=\"cover\" content=\"\\1\""); ++ TextResource::SetText(source); ++ TextResource::SaveToDisk(book_wide_save); ++} ++ ++ ++QString OPFResource::GetPackageVersion() const ++{ ++ QReadLocker locker(&GetLock()); ++ // The right way to do this is to properly parse the opf. ++ // That means invoking the embedded python code and lxml. ++ // As this code will be called many times and from many places ++ // convert it to a simple QRegualr expression query for speed. ++ ++ // QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ // OPFParser p; ++ // p.parse(source); ++ // return p.m_package.m_version; ++ ++ QString opftext = GetText(); ++ QRegularExpression pkgversion_search(PKG_VERSION, QRegularExpression::CaseInsensitiveOption); ++ QRegularExpressionMatch pkgversion_mo = pkgversion_search.match(opftext); ++ QString version = "2.0"; ++ if (pkgversion_mo.hasMatch()) { ++ version = pkgversion_mo.captured(1); ++ } ++ return version; ++} ++ ++ ++QString OPFResource::GetUUIDIdentifierValue() ++{ ++ EnsureUUIDIdentifierPresent(); ++ QReadLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ for (int i=0; i < p.m_metadata.count(); ++i) { ++ MetaEntry me = p.m_metadata.at(i); ++ if(me.m_name.startsWith("dc:identifier")) { ++ QString value = QString(me.m_content).remove("urn:uuid:"); ++ if (!QUuid(value).isNull()) { ++ return value; ++ } ++ } ++ } ++ // EnsureUUIDIdentifierPresent should ensure we ++ // never reach here. ++ Q_ASSERT(false); ++ return QString(); ++} ++ ++ ++void OPFResource::EnsureUUIDIdentifierPresent() ++{ ++ QWriteLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ for (int i=0; i < p.m_metadata.count(); ++i) { ++ MetaEntry me = p.m_metadata.at(i); ++ if(me.m_name.startsWith("dc:identifier")) { ++ QString value = QString(me.m_content).remove("urn:uuid:"); ++ if (!QUuid(value).isNull()) { ++ return; ++ } ++ } ++ } ++ QString uuid = Utility::CreateUUID(); ++ // add in the proper identifier type prefix ++ if (!uuid.startsWith("urn:uuid:")) { ++ uuid = "urn:uuid:" + uuid; ++ } ++ WriteIdentifier("UUID", uuid, p); ++ UpdateText(p); ++} ++ ++// This routine add the NCX to the OPF Mainifest ++// ncx_path is the full absolute file path to the ncx ++QString OPFResource::AddNCXItem(const QString &ncx_path, QString id) ++{ ++ QWriteLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ QString ncx_bkpath = ncx_path.right(ncx_path.length() - GetFullPathToBookFolder().length() - 1); ++ QString ncx_rel_path = Utility::buildRelativePath(GetRelativePath(), ncx_bkpath); ++ int n = p.m_manifest.count(); ++ ManifestEntry me; ++ me.m_id = GetUniqueID(id, p); ++ me.m_href = Utility::URLEncodePath(ncx_rel_path); ++ me.m_mtype = "application/x-dtbncx+xml"; ++ p.m_manifest.append(me); ++ p.m_idpos[me.m_id] = n; ++ p.m_hrefpos[me.m_href] = n; ++ UpdateText(p); ++ return me.m_id; ++} ++ ++ ++void OPFResource::UpdateNCXOnSpine(const QString &new_ncx_id) ++{ ++ QWriteLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ QString ncx_id = p.m_spineattr.m_atts.value(QString("toc"),""); ++ if (new_ncx_id != ncx_id) { ++ p.m_spineattr.m_atts[QString("toc")] = new_ncx_id; ++ UpdateText(p); ++ } ++} ++ ++void OPFResource::RemoveNCXOnSpine() ++{ ++ QWriteLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ p.m_spineattr.m_atts.remove("toc"); ++ UpdateText(p); ++} ++ ++ ++void OPFResource::UpdateNCXLocationInManifest(const NCXResource *ncx) ++{ ++ QWriteLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ QString ncx_id = p.m_spineattr.m_atts.value(QString("toc"), ""); ++ int pos = p.m_idpos.value(ncx_id, -1); ++ if (pos > -1) { ++ ManifestEntry me = p.m_manifest.at(pos); ++ QString href = me.m_href; ++ QString new_href = Utility::URLEncodePath(GetRelativePathToResource(ncx)); ++ me.m_href = new_href; ++ p.m_manifest.replace(pos, me); ++ p.m_hrefpos.remove(href); ++ p.m_hrefpos[new_href] = pos; ++ UpdateText(p); ++ } ++} ++ ++ ++void OPFResource::AddSigilVersionMeta() ++{ ++ QWriteLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ for (int i=0; i < p.m_metadata.count(); ++i) { ++ MetaEntry me = p.m_metadata.at(i); ++ if ((me.m_name == "meta") && (me.m_atts.contains("name"))) { ++ QString name = me.m_atts[QString("name")]; ++ if (name == SIGIL_VERSION_META_NAME) { ++ me.m_atts["content"] = QString(SIGIL_VERSION); ++ p.m_metadata.replace(i, me); ++ UpdateText(p); ++ return; ++ } ++ } ++ } ++ MetaEntry me; ++ me.m_name = "meta"; ++ me.m_atts[QString("name")] = QString("Sigil version"); ++ me.m_atts[QString("content")] = QString(SIGIL_VERSION); ++ p.m_metadata.append(me); ++ UpdateText(p); ++} ++ ++ ++bool OPFResource::IsCoverImage(const ImageResource *image_resource) const ++{ ++ QReadLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ QString resource_id = GetResourceManifestID(image_resource, p); ++ return IsCoverImageCheck(resource_id, p); ++} ++ ++ ++bool OPFResource::IsCoverImageCheck(QString resource_id, const OPFParser & p) const ++{ ++ int pos = GetCoverMeta(p); ++ if (pos > -1) { ++ MetaEntry me = p.m_metadata.at(pos); ++ return me.m_atts.value(QString("content"),QString("")) == resource_id; ++ } ++ return false; ++} ++ ++ ++bool OPFResource::CoverImageExists() const ++{ ++ QReadLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ return GetCoverMeta(p) > -1; ++} ++ ++ ++void OPFResource::AutoFixWellFormedErrors() ++{ ++ QWriteLocker locker(&GetLock()); ++ const QStringList TEXT_EXTS = QStringList() << "htm" << "html" << "xhtml"; ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ // auto fill in spine from manifest if completely empty ++ if (p.m_spine.count() == 0) { ++ std::vector< std::pair< QString, QString > > txts; ++ for (int i=0; i < p.m_manifest.count(); i++) { ++ ManifestEntry me = p.m_manifest.at(i); ++ QString ahref = Utility::URLDecodePath(me.m_href); ++ QString aid = me.m_id; ++ QString ext = QFileInfo(ahref).suffix(); ++ if ((me.m_mtype == "application/xhtml+xml") || TEXT_EXTS.contains(ext.toLower())) { ++ txts.push_back(std::make_pair(ahref, aid)); ++ } ++ } ++ std::sort(txts.begin(), txts.end(), Utility::sort_string_pairs_by_first); ++ for (unsigned int j=0; j < txts.size(); j++) { ++ QString idref = txts.at(j).second; ++ SpineEntry sp; ++ sp.m_idref = idref; ++ p.m_spine << sp; ++ } ++ } ++ UpdateText(p); ++} ++ ++ ++QStringList OPFResource::GetSpineOrderBookPaths() const ++{ ++ QReadLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ QStringList book_paths_in_reading_order; ++ for (int i=0; i < p.m_spine.count(); ++i) { ++ SpineEntry sp = p.m_spine.at(i); ++ QString idref = sp.m_idref; ++ int pos = p.m_idpos.value(idref,-1); ++ if (pos > -1) { ++ QString apath = Utility::URLDecodePath(p.m_manifest.at(pos).m_href); ++ book_paths_in_reading_order.append(Utility::buildBookPath(apath,GetFolder())); ++ } ++ } ++ return book_paths_in_reading_order; ++} ++ ++QString OPFResource::GetPrimaryBookTitle() const ++{ ++ QString title = ""; ++ QStringList titles = GetDCMetadataValues("dc:title"); ++ if (!titles.isEmpty()) { ++ title = titles.at(0); ++ } ++ return title; ++} ++ ++QString OPFResource::GetPrimaryBookLanguage() const ++{ ++ SettingsStore settings; ++ QString lang = settings.defaultMetadataLang(); ++ QStringList languages = GetDCMetadataValues("dc:language"); ++ if (!languages.isEmpty()) { ++ lang = languages.at(0); ++ } ++ return lang; ++} ++ ++QList<MetaEntry> OPFResource::GetDCMetadata() const ++{ ++ QReadLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ QList<MetaEntry> metadata; ++ for (int i=0; i < p.m_metadata.count(); ++i) { ++ if (p.m_metadata.at(i).m_name.startsWith("dc:")) { ++ MetaEntry me(p.m_metadata.at(i)); ++ metadata.append(me); ++ } ++ } ++ return metadata; ++} ++ ++ ++QStringList OPFResource::GetDCMetadataValues(QString text) const ++{ ++ QStringList metavalues; ++ foreach(MetaEntry meta, GetDCMetadata()) { ++ if (meta.m_name == text) { ++ metavalues.append(meta.m_content); ++ } ++ } ++ return metavalues; ++} ++ ++ ++void OPFResource::SetDCMetadata(const QList<MetaEntry> &metadata) ++{ ++ QWriteLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ // this will not work with refines so it needs to be fixed ++ RemoveDCElements(p); ++ foreach(MetaEntry book_meta, metadata) { ++ MetaEntry me(book_meta); ++ me.m_content = me.m_content.toHtmlEscaped(); ++ p.m_metadata.append(me); ++ } ++ UpdateText(p); ++} ++ ++ ++void OPFResource::AddResource(const Resource *resource) ++{ ++ QWriteLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ ManifestEntry me; ++ me.m_id = GetUniqueID(GetValidID(resource->Filename()),p); ++ me.m_href = Utility::URLEncodePath(GetRelativePathToResource(resource)); ++ me.m_mtype = GetResourceMimetype(resource); ++ // Argh! If this is an new blank resource - it will have no content yet ++ // so trying to parse it here to check for manifest properties is a mistake ++ int n = p.m_manifest.count(); ++ p.m_manifest.append(me); ++ p.m_idpos[me.m_id] = n; ++ p.m_hrefpos[me.m_href] = n; ++ if (resource->Type() == Resource::HTMLResourceType) { ++ SpineEntry se; ++ se.m_idref = me.m_id; ++ p.m_spine.append(se); ++ } ++ UpdateText(p); ++} ++ ++void OPFResource::RemoveCoverImageProperty(QString& resource_id, OPFParser& p) ++{ ++ // remove the cover image property from manifest with resource_id ++ if (!resource_id.isEmpty()) { ++ int pos = p.m_idpos.value(resource_id, -1); ++ if (pos >= 0 ) { ++ ManifestEntry me = p.m_manifest.at(p.m_idpos[resource_id]); ++ QString properties = me.m_atts.value("properties", ""); ++ if (properties.contains("cover-image")) { ++ properties = properties.remove("cover-image"); ++ properties = properties.simplified(); ++ } ++ me.m_atts.remove("properties"); ++ if (!properties.isEmpty()) { ++ me.m_atts["properties"] = properties; ++ } ++ p.m_manifest.replace(pos, me); ++ } ++ } ++} ++ ++ ++void OPFResource::AddCoverImageProperty(QString& resource_id, OPFParser& p) ++{ ++ // add the cover image property from manifest with resource_id ++ if (!resource_id.isEmpty()) { ++ int pos = p.m_idpos.value(resource_id, -1); ++ if (pos >= 0 ) { ++ ManifestEntry me = p.m_manifest.at(p.m_idpos[resource_id]); ++ QString properties = me.m_atts.value("properties", "cover-image"); ++ if (!properties.contains("cover-image")) { ++ properties = properties.append(" cover-image"); ++ } ++ me.m_atts.remove("properties"); ++ me.m_atts["properties"] = properties; ++ p.m_manifest.replace(pos, me); ++ } ++ } ++} ++ ++ ++void OPFResource::RemoveCoverMetaForImage(const Resource *resource, OPFParser& p) ++{ ++ int pos = GetCoverMeta(p); ++ QString resource_id = GetResourceManifestID(resource, p); ++ ++ // Remove entry if there is a cover in meta and if this file is marked as cover ++ if (pos > -1) { ++ MetaEntry me = p.m_metadata.at(pos); ++ if (me.m_atts.value(QString("content"),QString("")) == resource_id) { ++ p.m_metadata.removeAt(pos); ++ } ++ } ++} ++ ++void OPFResource::AddCoverMetaForImage(const Resource *resource, OPFParser &p) ++{ ++ int pos = GetCoverMeta(p); ++ QString resource_id = GetResourceManifestID(resource, p); ++ ++ // If a cover entry exists, update its id, else create one ++ if (pos > -1) { ++ MetaEntry me = p.m_metadata.at(pos); ++ me.m_atts["content"] = resource_id; ++ p.m_metadata.replace(pos, me); ++ } else { ++ MetaEntry me; ++ me.m_name = "meta"; ++ me.m_atts["name"] = "cover"; ++ me.m_atts["content"] = QString(resource_id); ++ p.m_metadata.append(me); ++ } ++} ++ ++ ++void OPFResource::BulkRemoveResources(const QList<Resource *>resources) ++{ ++ QWriteLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ if (p.m_manifest.isEmpty()) return; ++ ++ foreach(Resource * resource, resources) { ++ QString href = Utility::URLEncodePath(GetRelativePathToResource(resource)); ++ int pos = p.m_hrefpos.value(href, -1); ++ QString item_id = ""; ++ ++ // Delete the meta tag for cover images before deleting the manifest entry ++ if (resource->Type() == Resource::ImageResourceType) { ++ RemoveCoverMetaForImage(resource, p); ++ } ++ if (pos > -1) { ++ item_id = p.m_manifest.at(pos).m_id; ++ } ++ if (resource->Type() == Resource::HTMLResourceType) { ++ for (int i=0; i < p.m_spine.count(); ++i) { ++ QString idref = p.m_spine.at(i).m_idref; ++ if (idref == item_id) { ++ p.m_spine.removeAt(i); ++ break; ++ } ++ } ++ RemoveGuideReferenceForResource(resource, p); ++ QString version = GetEpubVersion(); ++ if (version.startsWith('3')) { ++ NavProcessor navproc(GetNavResource()); ++ navproc.RemoveLandmarkForResource(resource); ++ } ++ } ++ if (pos > -1) { ++ p.m_manifest.removeAt(pos); ++ // rebuild the maps since updating them item by item would be slower ++ p.m_idpos.clear(); ++ p.m_hrefpos.clear(); ++ for (int i=0; i < p.m_manifest.count(); ++i) { ++ p.m_idpos[p.m_manifest.at(i).m_id] = i; ++ p.m_hrefpos[p.m_manifest.at(i).m_href] = i; ++ } ++ } ++ } ++ UpdateText(p); ++} ++ ++ ++void OPFResource::RemoveResource(const Resource *resource) ++{ ++ QWriteLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ if (p.m_manifest.isEmpty()) return; ++ QString href = Utility::URLEncodePath(GetRelativePathToResource(resource)); ++ int pos = p.m_hrefpos.value(href, -1); ++ QString item_id = ""; ++ ++ // Delete the meta tag for cover images before deleting the manifest entry ++ if (resource->Type() == Resource::ImageResourceType) { ++ RemoveCoverMetaForImage(resource, p); ++ } ++ if (pos > -1) { ++ item_id = p.m_manifest.at(pos).m_id; ++ } ++ if (resource->Type() == Resource::HTMLResourceType) { ++ for (int i=0; i < p.m_spine.count(); ++i) { ++ QString idref = p.m_spine.at(i).m_idref; ++ if (idref == item_id) { ++ p.m_spine.removeAt(i); ++ break; ++ } ++ } ++ RemoveGuideReferenceForResource(resource, p); ++ QString version = GetEpubVersion(); ++ if (version.startsWith('3')) { ++ NavProcessor navproc(GetNavResource()); ++ navproc.RemoveLandmarkForResource(resource); ++ } ++ } ++ if (pos > -1) { ++ p.m_manifest.removeAt(pos); ++ // rebuild the maps since updating them item by item would be slower ++ p.m_idpos.clear(); ++ p.m_hrefpos.clear(); ++ for (int i=0; i < p.m_manifest.count(); ++i) { ++ p.m_idpos[p.m_manifest.at(i).m_id] = i; ++ p.m_hrefpos[p.m_manifest.at(i).m_href] = i; ++ } ++ } ++ UpdateText(p); ++} ++ ++ ++void OPFResource::ClearSemanticCodesInGuide() ++{ ++ QWriteLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ foreach(GuideEntry ge, p.m_guide) { ++ p.m_guide.removeAt(0); ++ } ++ UpdateText(p); ++} ++ ++ ++void OPFResource::AddGuideSemanticCode(HTMLResource *html_resource, QString new_code, bool toggle) ++{ ++ //first get primary book language ++ QString lang = GetPrimaryBookLanguage(); ++ QWriteLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ QString current_code = GetGuideSemanticCodeForResource(html_resource, p); ++ ++ if ((current_code != new_code) || !toggle) { ++ RemoveDuplicateGuideCodes(new_code, p); ++ SetGuideSemanticCodeForResource(new_code, html_resource, p, lang); ++ } else { ++ // If the current code is the same as the new one, ++ // we toggle it off. ++ RemoveGuideReferenceForResource(html_resource, p); ++ } ++ UpdateText(p); ++} ++ ++QString OPFResource::GetGuideSemanticCodeForResource(const Resource *resource, const OPFParser &p) const ++{ ++ QString gtype; ++ int pos = GetGuideReferenceForResourcePos(resource, p); ++ if (pos > -1) { ++ GuideEntry ge = p.m_guide.at(pos); ++ gtype = ge.m_type; ++ } ++ return gtype; ++} ++ ++int OPFResource::GetGuideReferenceForResourcePos(const Resource *resource, const OPFParser &p) const ++{ ++ QString href_to_resource_from_opf = Utility::URLEncodePath(GetRelativePathToResource(resource)); ++ for (int i=0; i < p.m_guide.count(); ++i) { ++ GuideEntry ge = p.m_guide.at(i); ++ QString href = ge.m_href; ++ QStringList parts = href.split('#', QT_ENUM_KEEPEMPTYPARTS); ++ if (parts.at(0) == href_to_resource_from_opf) { ++ return i; ++ } ++ } ++ return -1; ++} ++ ++void OPFResource::RemoveDuplicateGuideCodes(QString code, OPFParser& p) ++{ ++ // Industry best practice is to have only one ++ // <guide> reference type instance per xhtml file. ++ // For NoType, there is nothing to remove. ++ if (code.isEmpty()) return; ++ if (p.m_guide.isEmpty()) return; ++ ++ // build up the list to be deleted in reverse order ++ QList<int> dellist; ++ for (int i = p.m_guide.count() - 1; i >= 0; --i) { ++ GuideEntry ge = p.m_guide.at(i); ++ QString gtype = ge.m_type; ++ if (gtype == code) { ++ dellist.append(i); ++ } ++ } ++ // remove them from the list in reverse order ++ foreach(int index, dellist) { ++ p.m_guide.removeAt(index); ++ } ++} ++ ++void OPFResource::RemoveGuideReferenceForResource(const Resource *resource, OPFParser& p) ++{ ++ // if guide hrefs use fragments, the same resource may be there in multiple ++ // guide entries. Since resource being deleted, remove them all ++ if (p.m_guide.isEmpty()) return; ++ int pos = GetGuideReferenceForResourcePos(resource, p); ++ while((pos > -1) && (!p.m_guide.isEmpty())) { ++ p.m_guide.removeAt(pos); ++ pos = GetGuideReferenceForResourcePos(resource, p); ++ } ++} ++ ++ ++void OPFResource::UpdateGuideFragments(QHash<QString,QString> &idupdates) ++{ ++ QWriteLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ for(int c=0; c < p.m_guide.size(); c++) { ++ GuideEntry ge = p.m_guide.at(c); ++ QString href = ge.m_href; ++ std::pair<QString, QString> parts = Utility::parseRelativeHREF(href); ++ QString apath = Utility::URLDecodePath(parts.first); ++ QString bkpath = Utility::buildBookPath(apath, GetFolder()); ++ QString key = bkpath + parts.second; ++ QString newid = idupdates.value(key,""); ++ if (!newid.isEmpty()) { ++ // found a fragment id needing to be updated ++ parts.second = "#" + newid; ++ href = Utility::buildRelativeHREF(apath, parts.second); ++ ge.m_href = href; ++ p.m_guide[c] = ge; ++ } ++ } ++ UpdateText(p); ++} ++ ++ ++// first merged resource in list is the sink resource ++void OPFResource::UpdateGuideAfterMerge(QList<Resource*> &merged_resources, QHash<QString,QString> §ion_id_map) ++{ ++ if (merged_resources.isEmpty() || merged_resources.size() < 2) return; ++ Resource* sink_resource = merged_resources.at(0); ++ QString sink_bookpath = sink_resource->GetRelativePath(); ++ QStringList merged_bookpaths; ++ for (int i=1; i < merged_resources.size(); i++) { ++ Resource* res = merged_resources.at(i); ++ merged_bookpaths << res->GetRelativePath(); ++ } ++ QWriteLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ for(int c=0; c < p.m_guide.size(); c++) { ++ GuideEntry ge = p.m_guide.at(c); ++ QString href = ge.m_href; ++ std::pair<QString, QString> parts = Utility::parseRelativeHREF(href); ++ QString apath = Utility::URLDecodePath(parts.first); ++ QString bkpath = Utility::buildBookPath(apath, GetFolder()); ++ if (merged_bookpaths.contains(bkpath)) { ++ // need to redirect this bookpath to destination bookpath ++ // handle nay redirect to new injected section fragments ++ if (parts.second.isEmpty()) { ++ if (section_id_map.contains(bkpath)) { ++ parts.second = "#" + section_id_map[bkpath]; ++ } ++ } ++ apath = Utility::buildRelativePath(GetRelativePath(), sink_bookpath); ++ href = Utility::buildRelativeHREF(apath, parts.second); ++ ge.m_href = href; ++ p.m_guide[c] = ge; ++ } ++ } ++ UpdateText(p); ++} ++ ++void OPFResource::SetGuideSemanticCodeForResource(QString code, const Resource *resource, OPFParser& p, const QString &lang) ++{ ++ if (code.isEmpty()) return; ++ int pos = GetGuideReferenceForResourcePos(resource, p); ++ QString title = GuideItems::instance()->GetTitle(code, lang); ++ if (pos > -1) { ++ GuideEntry ge = p.m_guide.at(pos); ++ ge.m_type = code; ++ ge.m_title = title; ++ p.m_guide.replace(pos, ge); ++ } else { ++ GuideEntry ge; ++ ge.m_type = code; ++ ge.m_title = title; ++ ge.m_href = Utility::URLEncodePath(GetRelativePathToResource(resource)); ++ p.m_guide.append(ge); ++ } ++} ++ ++ ++QString OPFResource::GetGuideSemanticCodeForResource(const Resource *resource) const ++{ ++ QReadLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ return GetGuideSemanticCodeForResource(resource, p); ++} ++ ++ ++QString OPFResource::GetGuideSemanticNameForResource(Resource *resource) ++{ ++ return GuideItems::instance()->GetName(GetGuideSemanticCodeForResource(resource)); ++} ++ ++ ++QHash <QString, QString> OPFResource::GetSemanticCodeForPaths() ++{ ++ QReadLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ ++ QHash <QString, QString> semantic_types; ++ foreach(GuideEntry ge, p.m_guide) { ++ QString href = ge.m_href; ++ QStringList parts = href.split('#', QT_ENUM_KEEPEMPTYPARTS); ++ QString apath = Utility::URLDecodePath(parts.at(0)); ++ QString bkpath = Utility::buildBookPath(apath, GetFolder()); ++ QString gtype = ge.m_type; ++ semantic_types[bkpath] = gtype; ++ } ++ return semantic_types; ++} ++ ++ ++QHash <QString, QString> OPFResource::GetGuideSemanticNameForPaths() ++{ ++ QReadLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ ++ QHash <QString, QString> semantic_types; ++ foreach(GuideEntry ge, p.m_guide) { ++ QString href = ge.m_href; ++ QStringList parts = href.split('#', QT_ENUM_KEEPEMPTYPARTS); ++ QString gtype = ge.m_type; ++ QString apath = Utility::URLDecodePath(parts.at(0)); ++ QString bkpath = Utility::buildBookPath(apath, GetFolder()); ++ semantic_types[bkpath] = GuideItems::instance()->GetName(gtype); ++ } ++ ++ // Cover image semantics don't use reference ++ int pos = GetCoverMeta(p); ++ if (pos > -1) { ++ MetaEntry me = p.m_metadata.at(pos); ++ QString cover_id = me.m_atts.value(QString("content"),QString("")); ++ ManifestEntry man = p.m_manifest.at(p.m_idpos[cover_id]); ++ QString apath = Utility::URLDecodePath(man.m_href); ++ QString bkpath = Utility::buildBookPath(apath, GetFolder()); ++ semantic_types[bkpath] = GuideItems::instance()->GetName("cover"); ++ } ++ return semantic_types; ++} ++ ++ ++void OPFResource::SetResourceAsCoverImage(ImageResource *image_resource) ++{ ++ QWriteLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ QString resource_id = GetResourceManifestID(image_resource, p); ++ ++ // First deal with any previous covers by removing ++ // related metadata and manifest properties ++ QString old_cover_resource_id; ++ int pos = GetCoverMeta(p); ++ if (pos > -1) { ++ MetaEntry me = p.m_metadata.at(pos); ++ old_cover_resource_id = me.m_atts.value(QString("content"),QString("")); ++ p.m_metadata.removeAt(pos); ++ } ++ if (!old_cover_resource_id.isEmpty()) { ++ if (p.m_package.m_version.startsWith("3")) { ++ RemoveCoverImageProperty(old_cover_resource_id, p); ++ } ++ } ++ ++ // Now add in new metadata and manifest properties ++ AddCoverMetaForImage(image_resource, p); ++ if (p.m_package.m_version.startsWith("3")) { ++ AddCoverImageProperty(resource_id, p); ++ } ++ UpdateText(p); ++} ++ ++ ++// note: under epub3 spine elements may have page properties set, so simply clearing the ++// spine will lose these attributes. We should try to keep as much of the spine properties ++// and linear attributes as we can. Either that or make the HTML Resource remember its own ++// spine page properties, linear attribute, etc ++ ++void OPFResource::UpdateSpineOrder(const QList<::HTMLResource *> html_files) ++{ ++ QWriteLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ QList<SpineEntry> new_spine; ++ foreach(HTMLResource * html_resource, html_files) { ++ const Resource *resource = static_cast<const Resource *>(html_resource); ++ QString id = GetResourceManifestID(resource, p); ++ int found = -1; ++ for (int i = 0; i < p.m_spine.count(); ++i) { ++ SpineEntry se = p.m_spine.at(i); ++ if (se.m_idref == id) { ++ found = i; ++ break; ++ } ++ } ++ if (found > -1) { ++ new_spine.append(p.m_spine.at(found)); ++ } else { ++ SpineEntry se; ++ se.m_idref = id; ++ new_spine.append(se); ++ } ++ } ++ p.m_spine.clear(); ++ p.m_spine = new_spine; ++ UpdateText(p); ++} ++ ++ ++void OPFResource::ResourceRenamed(const Resource *resource, QString old_full_path) ++{ ++ QWriteLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ // first convert old_full_path to old_bkpath ++ QString old_bkpath = old_full_path.right(old_full_path.length() - GetFullPathToBookFolder().length() - 1); ++ QString old_href = Utility::URLEncodePath(Utility::buildRelativePath(GetRelativePath(), old_bkpath)); ++ QString old_id; ++ QString new_id; ++ for (int i=0; i < p.m_manifest.count(); ++i) { ++ QString href = p.m_manifest.at(i).m_href; ++ if (href == old_href) { ++ ManifestEntry me = p.m_manifest.at(i); ++ QString old_me_href = me.m_href; ++ me.m_href = Utility::URLEncodePath(GetRelativePathToResource(resource)); ++ old_id = me.m_id; ++ p.m_idpos.remove(old_id); ++ new_id = GetUniqueID(GetValidID(resource->Filename()),p); ++ me.m_id = new_id; ++ p.m_idpos[new_id] = i; ++ p.m_hrefpos.remove(old_me_href); ++ p.m_hrefpos[me.m_href] = i; ++ p.m_manifest.replace(i, me); ++ break; ++ } ++ } ++ for (int i=0; i < p.m_spine.count(); ++i) { ++ QString idref = p.m_spine.at(i).m_idref; ++ if (idref == old_id) { ++ SpineEntry se = p.m_spine.at(i); ++ se.m_idref = new_id; ++ p.m_spine.replace(i, se); ++ break; ++ } ++ } ++ if (resource->Type() == Resource::NCXResourceType) { ++ // handle updating the ncx id on the spine if ncx renamed ++ QString ncx_id = p.m_spineattr.m_atts.value(QString("toc"),""); ++ if (new_id != ncx_id) { ++ p.m_spineattr.m_atts[QString("toc")] = new_id; ++ } ++ } ++ if (resource->Type() == Resource::ImageResourceType) { ++ // Change meta entry for cover if necessary ++ // Check using IDs since file is already renamed ++ if (IsCoverImageCheck(old_id, p)) { ++ // Add will automatically replace an existing id ++ // Assumes only one cover but removing duplicates ++ // can cause timing issues ++ AddCoverMetaForImage(resource, p); ++ } ++ } ++ UpdateText(p); ++} ++ ++ ++void OPFResource::ResourceMoved(const Resource *resource, QString old_full_path) ++{ ++ QWriteLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ // first convert old_full_path to old_bkpath ++ QString old_bkpath = old_full_path.right(old_full_path.length() - GetFullPathToBookFolder().length() - 1); ++ QString old_href = Utility::URLEncodePath(Utility::buildRelativePath(GetRelativePath(), old_bkpath)); ++ // a move should not impact the id so leave the old unique manifest id unchanged ++ for (int i=0; i < p.m_manifest.count(); ++i) { ++ QString href = p.m_manifest.at(i).m_href; ++ if (href == old_href) { ++ ManifestEntry me = p.m_manifest.at(i); ++ QString old_me_href = me.m_href; ++ me.m_href = Utility::URLEncodePath(GetRelativePathToResource(resource)); ++ p.m_idpos[me.m_id] = i; ++ p.m_hrefpos.remove(old_me_href); ++ p.m_hrefpos[me.m_href] = i; ++ p.m_manifest.replace(i, me); ++ break; ++ } ++ } ++ UpdateText(p); ++} ++ ++ ++int OPFResource::GetCoverMeta(const OPFParser& p) const ++{ ++ for (int i = 0; i < p.m_metadata.count(); ++i) { ++ MetaEntry me = p.m_metadata.at(i); ++ if ((me.m_name == "meta") && (me.m_atts.contains(QString("name")))) { ++ QString name = me.m_atts[QString("name")]; ++ if (name == "cover") { ++ return i; ++ } ++ } ++ } ++ return -1; ++} ++ ++ ++int OPFResource::GetMainIdentifier(const OPFParser& p) const ++{ ++ QString unique_identifier = p.m_package.m_uniqueid; ++ for (int i=0; i < p.m_metadata.count(); ++i) { ++ MetaEntry me = p.m_metadata.at(i); ++ if (me.m_name == "dc:identifier") { ++ QString id = me.m_atts.value("id", ""); ++ if (id == unique_identifier) { ++ return i; ++ } ++ } ++ } ++ return -1; ++} ++ ++QHash<QString, Resource*>OPFResource::GetManifestIDResourceMapping(const QList<Resource *> &resources, ++ const OPFParser &p) ++{ ++ QHash<QString, Resource*> id_mapping; ++ foreach(Resource * resource, resources) { ++ QString href_path = Utility::URLEncodePath(GetRelativePathToResource(resource)); ++ int pos = p.m_hrefpos.value(href_path,-1); ++ if (pos > -1) { ++ id_mapping[ p.m_manifest.at(pos).m_id ] = resource; ++ } ++ } ++ return id_mapping; ++} ++ ++ ++QString OPFResource::GetResourceManifestID(const Resource *resource, const OPFParser& p) const ++{ ++ QString href_path = Utility::URLEncodePath(GetRelativePathToResource(resource)); ++ int pos = p.m_hrefpos.value(href_path,-1); ++ if (pos > -1) { ++ return QString(p.m_manifest.at(pos).m_id); ++ } ++ qDebug() << "GetResourceMainfestID returning null" << href_path; ++ return QString(); ++} ++ ++ ++QHash<Resource *, QString> OPFResource::GetResourceManifestIDMapping(const QList<Resource *> &resources, ++ const OPFParser& p) ++{ ++ QHash<Resource *, QString> id_mapping; ++ QStringList keys = p.m_hrefpos.keys(); ++ foreach(Resource * resource, resources) { ++ QString href_path = Utility::URLEncodePath(GetRelativePathToResource(resource)); ++ // empty relative path from the OPF is the OPF which will not have a manifest entry ++ if (!href_path.isEmpty()) { ++ int pos = p.m_hrefpos.value(href_path,-1); ++ if (pos > -1) { ++ id_mapping[ resource ] = p.m_manifest.at(pos).m_id; ++ } else { ++ qDebug() << "GetResourceMainifestIDMapping no map for" << href_path; ++ } ++ } ++ } ++ return id_mapping; ++} ++ ++ ++void OPFResource::RemoveDCElements(OPFParser& p) ++{ ++ int pos = GetMainIdentifier(p); ++ // build list to be delted in reverse order ++ QList<int> dellist; ++ int n = p.m_metadata.count(); ++ for (int i = n-1; i >= 0; --i) { ++ MetaEntry me = p.m_metadata.at(i); ++ if (me.m_name.startsWith("dc:")) { ++ if (i != pos) { ++ dellist.append(i); ++ } ++ } ++ } ++ // delete the MetaEntries in reverse order to not mess up indexes ++ foreach(int index, dellist) { ++ p.m_metadata.removeAt(index); ++ } ++} ++ ++ ++void OPFResource::WriteSimpleMetadata(const QString &metaname, const QString &metavalue, OPFParser& p) ++{ ++ MetaEntry me; ++ me.m_name = QString("dc:") + metaname; ++ me.m_content = metavalue.toHtmlEscaped(); ++ p.m_metadata.append(me); ++} ++ ++ ++void OPFResource::WriteIdentifier(const QString &metaname, const QString &metavalue, OPFParser& p) ++{ ++ int pos = GetMainIdentifier(p); ++ if (pos > -1) { ++ MetaEntry me = p.m_metadata.at(pos); ++ QString scheme = me.m_atts.value(QString("scheme"),QString("")); ++ // epub3 no longer uses the scheme attribute ++ if (scheme.isEmpty() && me.m_content.startsWith("urn:uuid:")) scheme="UUID"; ++ if ((metavalue == me.m_content) && (metaname == scheme)) { ++ return; ++ } ++ } ++ QString epubversion = GetEpubVersion(); ++ MetaEntry me; ++ me.m_name = QString("dc:identifier"); ++ // under the latest epub3 spec "scheme" is no longer an allowed attribute of dc:identifier ++ if (epubversion.startsWith('2')) { ++ me.m_atts[QString("opf:scheme")] = metaname; ++ } ++ if (metaname.toLower() == "uuid" && !metavalue.contains("urn:uuid:")) { ++ me.m_content = QString("urn:uuid:") + metavalue; ++ } else { ++ me.m_content = metavalue; ++ } ++ p.m_metadata.append(me); ++} ++ ++QString OPFResource::AddModificationDateMeta() ++{ ++ QString datetime; ++ QDateTime local(QDateTime::currentDateTime()); ++ local.setTimeSpec(Qt::UTC); ++ datetime = local.toString(Qt::ISODate); ++ ++ QWriteLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ ++ QString epubversion = GetEpubVersion(); ++ if (epubversion.startsWith('3')) { ++ ++ // epub 3 set dcterms:modified date time in ISO 8601 format ++ // if an entry exists, update it ++ for (int i=0; i < p.m_metadata.count(); ++i) { ++ MetaEntry me = p.m_metadata.at(i); ++ if (me.m_name == QString("meta")) { ++ QString property = me.m_atts.value(QString("property"), QString("")); ++ if (property == QString("dcterms:modified")) { ++ me.m_content = datetime; ++ p.m_metadata.replace(i, me); ++ UpdateText(p); ++ return datetime; ++ } ++ } ++ } ++ // otherwize create a new entry ++ MetaEntry me; ++ me.m_name = QString("meta"); ++ me.m_content = datetime; ++ me.m_atts["property"]="dcterms:modified"; ++ p.m_metadata.append(me); ++ UpdateText(p); ++ return datetime; ++ } ++ // epub 2 version ++ QString date; ++ QDate d = QDate::currentDate(); ++ // We can't use QDate.toString() because it will take into account the locale. Which mean we may not get Arabic ++ // numerals if the local uses it's own numbering system. So we use this instead to ensure we get a valid date per ++ // the epub spec. ++ QTextStream(&date) << d.year() << "-" << (d.month() < 10 ? "0" : "") << d.month() << "-" << (d.day() < 10 ? "0" : "") << d.day(); ++ // if an entry exists, update it ++ for (int i=0; i < p.m_metadata.count(); ++i) { ++ MetaEntry me = p.m_metadata.at(i); ++ if (me.m_name == QString("dc:date")) { ++ QString etype = me.m_atts.value(QString("opf:event"), QString("")); ++ if (etype == QString("modification")) { ++ me.m_content = date; ++ p.m_metadata.replace(i, me); ++ UpdateText(p); ++ return datetime; ++ } ++ ++ } ++ } ++ // otherwize create a new entry ++ MetaEntry me; ++ me.m_name = QString("dc:date"); ++ me.m_content = date; ++ me.m_atts["xmlns:opf"]="http://www.idpf.org/2007/opf"; ++ me.m_atts[QString("opf:event")] = QString("modification"); ++ p.m_metadata.append(me); ++ UpdateText(p); ++ return datetime; ++} ++ ++ ++QString OPFResource::GetOPFDefaultText(const QString &version) ++{ ++ SettingsStore ss; ++ QString defaultLanguage = ss.defaultMetadataLang(); ++ if (version.startsWith('2')) { ++ return TEMPLATE_TEXT.arg(Utility::CreateUUID()).arg(defaultLanguage).arg(tr("[Title here]")); ++ } ++ // epub 3 set dcterms:modified date time in ISO 8601 format ++ QDateTime local(QDateTime::currentDateTime()); ++ local.setTimeSpec(Qt::UTC); ++ QString datetime = local.toString(Qt::ISODate); ++ return TEMPLATE3_TEXT.arg(Utility::CreateUUID()).arg(defaultLanguage).arg(tr("[Main title here]")).arg(datetime); ++} ++ ++ ++void OPFResource::FillWithDefaultText(const QString &version) ++{ ++ QString epubversion = version; ++ if (epubversion.isEmpty()) { ++ SettingsStore ss; ++ epubversion = ss.defaultVersion(); ++ } ++ SetEpubVersion(epubversion); ++ SetText(GetOPFDefaultText(epubversion)); ++} ++ ++ ++QString OPFResource::GetUniqueID(const QString &preferred_id, const OPFParser& p) const ++{ ++ if (p.m_idpos.contains(preferred_id)) { ++ return QString("x").append(Utility::CreateUUID()); ++ } ++ return preferred_id; ++} ++ ++ ++QString OPFResource::GetResourceMimetype(const Resource *resource) const ++{ ++ QString mimetype = resource->GetMediaType(); ++ if (mimetype.isEmpty()) { ++ mimetype = GetFileMimetype(resource->Filename()); ++ } ++ return mimetype; ++} ++ ++ ++QString OPFResource::GetFileMimetype(const QString &filepath) const ++{ ++ MediaTypes * MTMap = MediaTypes::instance(); ++ QString extension = QFileInfo(filepath).suffix().toLower(); ++ return MTMap->GetMediaTypeFromExtension(extension, FALLBACK_MIMETYPE); ++} ++ ++ ++void OPFResource::UpdateText(const OPFParser &p) ++{ ++ TextResource::SetText(p.convert_to_xml()); ++} ++ ++ ++QString OPFResource::ValidatePackageVersion(const QString& source) ++{ ++ QString newsource = source; ++ QString orig_version = GetEpubVersion(); ++ QRegularExpression pkgversion_search(PKG_VERSION, QRegularExpression::CaseInsensitiveOption); ++ QRegularExpressionMatch mo = pkgversion_search.match(newsource); ++ if (mo.hasMatch()) { ++ QString version = mo.captured(1); ++ if (version != orig_version) { ++ newsource.replace(mo.capturedStart(1), mo.capturedLength(1), orig_version); ++ if (!m_WarnedAboutVersion && !version.startsWith('1')) { ++ Utility::DisplayStdWarningDialog("Changing package version inside Sigil is not supported", ++ "Use an appropriate output plugin to make the initial conversion"); ++ m_WarnedAboutVersion = true; ++ } ++ } ++ } ++ return newsource; ++} ++ ++ ++void OPFResource::UpdateManifestProperties(const QList<Resource*> resources) ++{ ++ QWriteLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ if (p.m_package.m_version != "3.0") { ++ return; ++ } ++ foreach(Resource* resource, resources) { ++ const HTMLResource* html_resource = static_cast<const HTMLResource *>(resource); ++ // do not overwrite the nav property, it must stay no matter what ++ if (html_resource != m_NavResource) { ++ QString href = Utility::URLEncodePath(GetRelativePathToResource(html_resource)); ++ int pos = p.m_hrefpos.value(href, -1); ++ if ((pos >= 0) && (pos < p.m_manifest.count())) { ++ ManifestEntry me = p.m_manifest.at(pos); ++ QStringList properties = html_resource->GetManifestProperties(); ++ me.m_atts.remove("properties"); ++ if (properties.count() > 0) { ++ me.m_atts["properties"] = properties.join(QString(" ")); ++ } ++ p.m_manifest.replace(pos, me); ++ } ++ } ++ } ++ // now add the cover-image properties ++ int metapos = GetCoverMeta(p); ++ if (metapos > -1) { ++ MetaEntry cmeta = p.m_metadata.at(metapos); ++ QString cover_id = cmeta.m_atts.value(QString("content"),QString("")); ++ if (!cover_id.isEmpty()) { ++ int pos = p.m_idpos.value(cover_id, -1); ++ if (pos >= 0 ) { ++ ManifestEntry me = p.m_manifest.at(p.m_idpos[cover_id]); ++ me.m_atts.remove("properties"); ++ me.m_atts["properties"] = QString("cover-image"); ++ p.m_manifest.replace(pos, me); ++ } ++ } ++ } ++ UpdateText(p); ++} ++ ++ ++QString OPFResource::GetManifestPropertiesForResource(const Resource * resource) ++{ ++ QString properties; ++ if (!resource) return properties; ++ QReadLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ if (!p.m_package.m_version.startsWith("3")) { ++ return properties; ++ } ++ QString href = Utility::URLEncodePath(GetRelativePathToResource(resource)); ++ int pos = p.m_hrefpos.value(href, -1); ++ if ((pos >= 0) && (pos < p.m_manifest.count())) { ++ ManifestEntry me = p.m_manifest.at(pos); ++ properties = me.m_atts.value("properties",""); ++ } ++ return properties; ++} ++ ++ ++QHash <QString, QString> OPFResource::GetManifestPropertiesForPaths() ++{ ++ QHash <QString, QString> manifest_properties_all; ++ QString version = GetEpubVersion(); ++ if (!version.startsWith('3')) { ++ return manifest_properties_all; ++ } ++ QReadLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ foreach(ManifestEntry me, p.m_manifest) { ++ QString apath = Utility::URLDecodePath(me.m_href); ++ if (me.m_atts.contains("properties")){ ++ QString properties = me.m_atts["properties"]; ++ apath = Utility::buildBookPath(apath, GetFolder()); ++ manifest_properties_all[apath] = properties; ++ } ++ } ++ return manifest_properties_all; ++} ++ ++ ++HTMLResource * OPFResource::GetNavResource()const ++{ ++ return m_NavResource; ++} ++ ++ ++void OPFResource::SetNavResource(HTMLResource * nav_resource) ++{ ++ m_NavResource = nav_resource; ++ // Make sure the proper nav property is set in the opf manifest ++ if (m_NavResource) { ++ QWriteLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ QString href = Utility::URLEncodePath(GetRelativePathToResource(m_NavResource)); ++ int pos = p.m_hrefpos.value(href, -1); ++ if ((pos >= 0) && (pos < p.m_manifest.count())) { ++ ManifestEntry me = p.m_manifest.at(pos); ++ me.m_atts["properties"] = QString("nav"); ++ p.m_manifest.replace(pos, me); ++ } ++ UpdateText(p); ++ } ++} ++ ++ ++void OPFResource::SetItemRefLinear(Resource * resource, bool linear) ++{ ++ QWriteLocker locker(&GetLock()); ++ QString source = CleanSource::ProcessXML(GetText(),"application/oebps-package+xml"); ++ OPFParser p; ++ p.parse(source); ++ QString resource_href_path = Utility::URLEncodePath(GetRelativePathToResource(resource)); ++ int pos = p.m_hrefpos.value(resource_href_path, -1); ++ QString item_id = ""; ++ if (pos > -1) { ++ item_id = p.m_manifest.at(pos).m_id; ++ if (resource->Type() == Resource::HTMLResourceType) { ++ for (int i=0; i < p.m_spine.count(); ++i) { ++ QString idref = p.m_spine.at(i).m_idref; ++ if (idref == item_id) { ++ SpineEntry se = p.m_spine.at(i); ++ se.m_atts.remove(QString("linear")); ++ // default is linear = "yes" ++ if (!linear) { ++ se.m_atts[QString("linear")] = QString("no"); ++ } ++ p.m_spine.replace(i, se); ++ break; ++ } ++ } ++ } ++ UpdateText(p); ++ } ++} +-- +2.42.0 + diff --git a/0003-don-t-write-version-and-modified-tags.patch b/0003-don-t-write-version-and-modified-tags.patch new file mode 100644 index 000000000000..7039c91ba00f --- /dev/null +++ b/0003-don-t-write-version-and-modified-tags.patch @@ -0,0 +1,108 @@ +From 23d899891c3db7e09a72e16e2cfbadaee7285ebe Mon Sep 17 00:00:00 2001 +From: xiota +Date: Sun, 29 Oct 2023 03:53:13 -0700 +Subject: [PATCH 3/3] don't write version and modified tags + +Don't write version and modification tags to the opf. +Results in a somewhat cleaner opf. +--- + src/ResourceObjects/OPFResource.cpp | 30 +++--------------------- + src/ResourceObjects/OPFResource.cpp.orig | 14 ----------- + 2 files changed, 3 insertions(+), 41 deletions(-) + +diff --git a/src/ResourceObjects/OPFResource.cpp b/src/ResourceObjects/OPFResource.cpp +index 7f7020b..5f79772 100644 +--- a/src/ResourceObjects/OPFResource.cpp ++++ b/src/ResourceObjects/OPFResource.cpp +@@ -464,18 +464,11 @@ void OPFResource::AddSigilVersionMeta() + QString name = me.m_atts[QString("name")]; + if (name == SIGIL_VERSION_META_NAME) { + me.m_atts["content"] = QString(SIGIL_VERSION); +- p.m_metadata.replace(i, me); +- UpdateText(p); ++ p.m_metadata.removeAt(i); + return; + } + } + } +- MetaEntry me; +- me.m_name = "meta"; +- me.m_atts[QString("name")] = QString("Sigil version"); +- me.m_atts[QString("content")] = QString(SIGIL_VERSION); +- p.m_metadata.append(me); +- UpdateText(p); + } + + +@@ -1382,19 +1375,11 @@ QString OPFResource::AddModificationDateMeta() + QString property = me.m_atts.value(QString("property"), QString("")); + if (property == QString("dcterms:modified")) { + me.m_content = datetime; +- p.m_metadata.replace(i, me); +- UpdateText(p); ++ p.m_metadata.removeAt(i); + return datetime; + } + } + } +- // otherwize create a new entry +- MetaEntry me; +- me.m_name = QString("meta"); +- me.m_content = datetime; +- me.m_atts["property"]="dcterms:modified"; +- p.m_metadata.append(me); +- UpdateText(p); + return datetime; + } + // epub 2 version +@@ -1411,21 +1396,12 @@ QString OPFResource::AddModificationDateMeta() + QString etype = me.m_atts.value(QString("opf:event"), QString("")); + if (etype == QString("modification")) { + me.m_content = date; +- p.m_metadata.replace(i, me); +- UpdateText(p); ++ p.m_metadata.removeAt(i); + return datetime; + } + + } + } +- // otherwize create a new entry +- MetaEntry me; +- me.m_name = QString("dc:date"); +- me.m_content = date; +- me.m_atts["xmlns:opf"]="http://www.idpf.org/2007/opf"; +- me.m_atts[QString("opf:event")] = QString("modification"); +- p.m_metadata.append(me); +- UpdateText(p); + return datetime; + } + +diff --git a/src/ResourceObjects/OPFResource.cpp.orig b/src/ResourceObjects/OPFResource.cpp.orig +index 4b7668d..7f7020b 100644 +--- a/src/ResourceObjects/OPFResource.cpp.orig ++++ b/src/ResourceObjects/OPFResource.cpp.orig +@@ -1493,20 +1493,6 @@ void OPFResource::UpdateText(const OPFParser &p) + QString OPFResource::ValidatePackageVersion(const QString& source) + { + QString newsource = source; +- QString orig_version = GetEpubVersion(); +- QRegularExpression pkgversion_search(PKG_VERSION, QRegularExpression::CaseInsensitiveOption); +- QRegularExpressionMatch mo = pkgversion_search.match(newsource); +- if (mo.hasMatch()) { +- QString version = mo.captured(1); +- if (version != orig_version) { +- newsource.replace(mo.capturedStart(1), mo.capturedLength(1), orig_version); +- if (!m_WarnedAboutVersion && !version.startsWith('1')) { +- Utility::DisplayStdWarningDialog("Changing package version inside Sigil is not supported", +- "Use an appropriate output plugin to make the initial conversion"); +- m_WarnedAboutVersion = true; +- } +- } +- } + return newsource; + } + +-- +2.42.0 + @@ -8,7 +8,7 @@ _localepurge= _pkgname=sigil pkgname="$_pkgname-git" -pkgver=2.0.2.r6.gd223713e5 +pkgver=2.0.2.r11.gb9438a876 pkgrel=1 pkgdesc='multi-platform EPUB2/EPUB3 ebook editor' arch=('x86_64') @@ -76,15 +76,15 @@ fi options=(!debug) source+=( - 'default_nav_css.patch' - 'skip_epub_version_check.patch' - 'skip_version_mod_tags.patch' + '0001-modify-default-navigation-css.patch' + '0002-skip-epub-version-check.patch' + '0003-don-t-write-version-and-modified-tags.patch' ) sha256sums+=( - '3478ff361a34fd7cd7811d5103cbace91ecc790463684aaab9e21687b5553a28' - 'fc2bdc23d13b2e917f08608b516495b744f991642f73c1f6d943cf322a25fc11' - 'c74be3af315c9ffe181df6b465d0037f152f6078b953e6eeaab7b2932ae4c729' + 'c01f2028fd2a77fa48ddeefc70b780d185131f81c8c3b3f4f3bfd670cd1d574f' + 'd06138d38a2d29ca020ec575bd2aa975df48cf61bbad975140fe5f304e23f6b0' + '4bddaaf8666e3d060ba51989c94d6c3a2c23a5b037dd69abe6c61af51b580720' ) prepare() { diff --git a/default_nav_css.patch b/default_nav_css.patch deleted file mode 100644 index fe49838156cb..000000000000 --- a/default_nav_css.patch +++ /dev/null @@ -1,21 +0,0 @@ -Subject: [PATCH] modify default navigation css - ---- old/src/BookManipulation/Book.cpp -+++ new/src/BookManipulation/Book.cpp -@@ -126,6 +126,16 @@ - "}\n\n" - "ol {\n" - " list-style-type: none;\n" -+ " padding-left: 1.5rem;\n" -+ "}\n\n" -+ "li > ol {\n" -+ " margin-bottom: 0.75rem;\n" -+ "}\n\n" -+ "li {\n" -+ " margin-top: 0.25rem;\n" -+ "}\n\n" -+ "a {\n" -+ " text-decoration: none;\n" - "}\n\n"; - - diff --git a/skip_epub_version_check.patch b/skip_epub_version_check.patch deleted file mode 100644 index b00f876b0952..000000000000 --- a/skip_epub_version_check.patch +++ /dev/null @@ -1,27 +0,0 @@ -Subject: [PATCH] skip epub version check -Description: allows changing from epub2 to epub3 by directly editing the opf - some data is lost and needs to be recreated (eg, table of contents) - ---- sigil.old/src/ResourceObjects/OPFResource.cpp -+++ sigil.new/src/ResourceObjects/OPFResource.cpp -@@ -1310,20 +1310,6 @@ - QString OPFResource::ValidatePackageVersion(const QString& source) - { - QString newsource = source; -- QString orig_version = GetEpubVersion(); -- QRegularExpression pkgversion_search(PKG_VERSION, QRegularExpression::CaseInsensitiveOption); -- QRegularExpressionMatch mo = pkgversion_search.match(newsource); -- if (mo.hasMatch()) { -- QString version = mo.captured(1); -- if (version != orig_version) { -- newsource.replace(mo.capturedStart(1), mo.capturedLength(1), orig_version); -- if (!m_WarnedAboutVersion && !version.startsWith('1')) { -- Utility::DisplayStdWarningDialog("Changing package version inside Sigil is not supported", -- "Use an appropriate output plugin to make the initial conversion"); -- m_WarnedAboutVersion = true; -- } -- } -- } - return newsource; - } - diff --git a/skip_version_mod_tags.patch b/skip_version_mod_tags.patch deleted file mode 100644 index fdffc085a3a8..000000000000 --- a/skip_version_mod_tags.patch +++ /dev/null @@ -1,70 +0,0 @@ -Subject: [PATCH] don't write version and modified tags -Description: Don't write version and modification tags to the opf. - Results in a somewhat cleaner opf. - ---- sigil.old/src/ResourceObjects/OPFResource.cpp -+++ sigil.new/src/ResourceObjects/OPFResource.cpp -@@ -422,18 +422,11 @@ - QString name = me.m_atts[QString("name")]; - if (name == SIGIL_VERSION_META_NAME) { - me.m_atts["content"] = QString(SIGIL_VERSION); -- p.m_metadata.replace(i, me); -- UpdateText(p); -+ p.m_metadata.removeAt(i); - return; - } - } - } -- MetaEntry me; -- me.m_name = "meta"; -- me.m_atts[QString("name")] = QString("Sigil version"); -- me.m_atts[QString("content")] = QString(SIGIL_VERSION); -- p.m_metadata.append(me); -- UpdateText(p); - } - - -@@ -1199,19 +1192,11 @@ - QString property = me.m_atts.value(QString("property"), QString("")); - if (property == QString("dcterms:modified")) { - me.m_content = datetime; -- p.m_metadata.replace(i, me); -- UpdateText(p); -+ p.m_metadata.removeAt(i); - return datetime; - } - } - } -- // otherwize create a new entry -- MetaEntry me; -- me.m_name = QString("meta"); -- me.m_content = datetime; -- me.m_atts["property"]="dcterms:modified"; -- p.m_metadata.append(me); -- UpdateText(p); - return datetime; - } - // epub 2 version -@@ -1228,21 +1213,12 @@ - QString etype = me.m_atts.value(QString("opf:event"), QString("")); - if (etype == QString("modification")) { - me.m_content = date; -- p.m_metadata.replace(i, me); -- UpdateText(p); -+ p.m_metadata.removeAt(i); - return datetime; - } - - } - } -- // otherwize create a new entry -- MetaEntry me; -- me.m_name = QString("dc:date"); -- me.m_content = date; -- me.m_atts["xmlns:opf"]="http://www.idpf.org/2007/opf"; -- me.m_atts[QString("opf:event")] = QString("modification"); -- p.m_metadata.append(me); -- UpdateText(p); - return datetime; - } - |