Beispiel #1
0
        private static EpubSpine ReadSpine(XElement spineNode)
        {
            var result       = new EpubSpine();
            var tocAttribute = spineNode.Attribute("toc");

            if (string.IsNullOrWhiteSpace(tocAttribute?.Value))
            {
                throw new Exception("Incorrect EPUB spine: TOC is missing");
            }

            result.Toc = tocAttribute?.Value;
            foreach (var spineItemNode in spineNode.Elements())
            {
                if (string.Compare(spineItemNode.Name.LocalName, "itemref", StringComparison.OrdinalIgnoreCase) is 0)
                {
                    var spineItemRef   = new EpubSpineItemRef();
                    var idRefAttribute = spineItemNode.Attribute("idref");
                    if (idRefAttribute is null || string.IsNullOrWhiteSpace(idRefAttribute.Value))
                    {
                        throw new Exception("Incorrect EPUB spine: item ID ref is missing");
                    }

                    spineItemRef.IdRef = idRefAttribute.Value;
                    var linearAttribute = spineItemNode.Attribute("linear");
                    spineItemRef.IsLinear = linearAttribute is null || string.Compare(linearAttribute.Value, "no", StringComparison.OrdinalIgnoreCase) != 0;
                    result.Add(spineItemRef);
                }
            }

            return(result);
        }
Beispiel #2
0
        private static EpubSpine ReadSpine(XmlNode spineNode)
        {
            EpubSpine    result       = new EpubSpine();
            XmlAttribute tocAttribute = spineNode.Attributes["toc"];

            if (tocAttribute == null || String.IsNullOrWhiteSpace(tocAttribute.Value))
            {
                throw new Exception("Incorrect EPUB spine: TOC is missing");
            }
            result.Toc = tocAttribute.Value;
            foreach (XmlNode spineItemNode in spineNode.ChildNodes)
            {
                if (String.Compare(spineItemNode.LocalName, "itemref", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    EpubSpineItemRef spineItemRef   = new EpubSpineItemRef();
                    XmlAttribute     idRefAttribute = spineItemNode.Attributes["idref"];
                    if (idRefAttribute == null || String.IsNullOrWhiteSpace(idRefAttribute.Value))
                    {
                        throw new Exception("Incorrect EPUB spine: item ID ref is missing");
                    }
                    spineItemRef.IdRef = idRefAttribute.Value;
                    XmlAttribute linearAttribute = spineItemNode.Attributes["linear"];
                    spineItemRef.IsLinear = linearAttribute == null || String.Compare(linearAttribute.Value, "no", StringComparison.OrdinalIgnoreCase) != 0;
                    result.Add(spineItemRef);
                }
            }
            return(result);
        }
        private static EpubSpine ReadSpine(XElement spineNode, EpubVersion epubVersion)
        {
            EpubSpine result = new EpubSpine();

            foreach (XAttribute spineNodeAttribute in spineNode.Attributes())
            {
                string attributeValue = spineNodeAttribute.Value;
                switch (spineNodeAttribute.GetLowerCaseLocalName())
                {
                case "id":
                    result.Id = attributeValue;
                    break;

                case "page-progression-direction":
                    result.PageProgressionDirection = PageProgressionDirectionParser.Parse(attributeValue);
                    break;

                case "toc":
                    result.Toc = attributeValue;
                    break;
                }
            }
            if (epubVersion == EpubVersion.EPUB_2 && String.IsNullOrWhiteSpace(result.Toc))
            {
                throw new Exception("Incorrect EPUB spine: TOC is missing");
            }
            foreach (XElement spineItemNode in spineNode.Elements())
            {
                if (spineItemNode.CompareNameTo("itemref"))
                {
                    EpubSpineItemRef spineItemRef = new EpubSpineItemRef();
                    foreach (XAttribute spineItemNodeAttribute in spineItemNode.Attributes())
                    {
                        string attributeValue = spineItemNodeAttribute.Value;
                        switch (spineItemNodeAttribute.GetLowerCaseLocalName())
                        {
                        case "id":
                            spineItemRef.Id = attributeValue;
                            break;

                        case "idref":
                            spineItemRef.IdRef = attributeValue;
                            break;

                        case "properties":
                            spineItemRef.Properties = SpinePropertyParser.ParsePropertyList(attributeValue);
                            break;
                        }
                    }
                    if (String.IsNullOrWhiteSpace(spineItemRef.IdRef))
                    {
                        throw new Exception("Incorrect EPUB spine: item ID ref is missing");
                    }
                    XAttribute linearAttribute = spineItemNode.Attribute("linear");
                    spineItemRef.IsLinear = linearAttribute == null || !linearAttribute.CompareValueTo("no");
                    result.Add(spineItemRef);
                }
            }
            return(result);
        }
Beispiel #4
0
        private static async Task <EpubSpine> ReadSpineAsync(XmlReader reader)
        {
            EpubSpine result     = new EpubSpine();
            bool      spineFound = await reader.ReadToFollowingAsync("spine", "http://www.idpf.org/2007/opf");

            if (!spineFound)
            {
                throw new Exception("EPUB parsing error: spine declarations not found in the package.");
            }

            if (String.IsNullOrWhiteSpace(reader.GetAttribute("toc")))
            {
                throw new Exception("Incorrect EPUB spine: TOC attribute is missing or empty");
            }
            result.Toc = reader.GetAttribute("toc");

            while (await reader.ReadAsync() && !(reader.NodeType == XmlNodeType.EndElement && reader.LocalName == "spine"))
            {
                if (reader.LocalName.ToLowerInvariant() == "itemref")
                {
                    EpubSpineItemRef spineItemRef = new EpubSpineItemRef();
                    spineItemRef.IsLinear = true;
                    while (reader.MoveToNextAttribute())
                    {
                        switch (reader.LocalName.ToLowerInvariant())
                        {
                        case "idref":
                            spineItemRef.IdRef = reader.Value;
                            break;

                        case "linear":
                            if (reader.Value.ToLowerInvariant() == "no")
                            {
                                spineItemRef.IsLinear = false;
                            }
                            break;
                        }
                    }
                    result.Add(spineItemRef);
                }
            }
            return(result);
        }
Beispiel #5
0
        public static List <EpubChapterRef> GetChapters(EpubBookRef bookRef, EpubSpine spine,
                                                        List <EpubNavigationPoint> navigationPoints)
        {
            var result = new List <EpubChapterRef>();

            for (var s = 0; s < spine.Count; s++)
            {
                var    itemRef = spine[s];
                string contentFileName;
                string anchor;
                contentFileName = WebUtility.UrlDecode(bookRef.Schema.Package.Manifest
                                                       .FirstOrDefault(e => e.Id == itemRef.IdRef)?.Href);
                anchor = null;
                if (!bookRef.Content.Html.TryGetValue(contentFileName, out var htmlContentFileRef))
                {
                    throw new Exception(string.Format("Incorrect EPUB manifest: item with href = \"{0}\" is missing.",
                                                      contentFileName));
                }
                var chapterRef = new EpubChapterRef(htmlContentFileRef);
                chapterRef.ContentFileName = contentFileName;
                chapterRef.Anchor          = anchor;
                chapterRef.Parent          = null;
                var navPoint = navigationPoints.LastOrDefault(nav =>
                                                              spine.Take(s + 1)
                                                              .Select(sp => bookRef.Schema.Package.Manifest.FirstOrDefault(e => e.Id == sp.IdRef)?.Href)
                                                              .Contains(nav.Content.Source.Split('#')[0]));
                if (navPoint != null)
                {
                    chapterRef.Title = navPoint.NavigationLabels.First().Text;
                }
                else
                {
                    chapterRef.Title = $"Chapter {s + 1}";
                }
                chapterRef.SubChapters = new List <EpubChapterRef>();
                result.Add(chapterRef);
            }

            return(result);
        }
Beispiel #6
0
        public static EpubPackage ReadPackage(ZipArchive epubArchive, string rootFilePath)
        {
            ZipArchiveEntry rootFileEntry = epubArchive.GetEntry(rootFilePath);

            if (rootFileEntry == null)
            {
                throw new Exception("EPUB parsing error: root file not found in archive.");
            }
            XmlDocument containerDocument;

            using (Stream containerStream = rootFileEntry.Open())
                containerDocument = XmlUtils.LoadDocument(containerStream);
            XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(containerDocument.NameTable);

            xmlNamespaceManager.AddNamespace("opf", "http://www.idpf.org/2007/opf");
            XmlNode     packageNode      = containerDocument.DocumentElement.SelectSingleNode("/opf:package", xmlNamespaceManager);
            EpubPackage result           = new EpubPackage();
            string      epubVersionValue = packageNode.Attributes["version"].Value;

            if (epubVersionValue == "2.0")
            {
                result.EpubVersion = EpubVersion.EPUB_2;
            }
            else
            if (epubVersionValue == "3.0")
            {
                result.EpubVersion = EpubVersion.EPUB_3;
            }
            else
            {
                throw new Exception(String.Format("Unsupported EPUB version: {0}.", epubVersionValue));
            }
            XmlNode metadataNode = packageNode.SelectSingleNode("opf:metadata", xmlNamespaceManager);

            if (metadataNode == null)
            {
                throw new Exception("EPUB parsing error: metadata not found in the package.");
            }
            EpubMetadata metadata = ReadMetadata(metadataNode, result.EpubVersion);

            result.Metadata = metadata;
            XmlNode manifestNode = packageNode.SelectSingleNode("opf:manifest", xmlNamespaceManager);

            if (manifestNode == null)
            {
                throw new Exception("EPUB parsing error: manifest not found in the package.");
            }
            EpubManifest manifest = ReadManifest(manifestNode);

            result.Manifest = manifest;
            XmlNode spineNode = packageNode.SelectSingleNode("opf:spine", xmlNamespaceManager);

            if (spineNode == null)
            {
                throw new Exception("EPUB parsing error: spine not found in the package.");
            }
            EpubSpine spine = ReadSpine(spineNode);

            result.Spine = spine;
            XmlNode guideNode = packageNode.SelectSingleNode("opf:guide", xmlNamespaceManager);

            if (guideNode != null)
            {
                EpubGuide guide = ReadGuide(guideNode);
                result.Guide = guide;
            }
            return(result);
        }
        private static async Task<EpubSpine> ReadSpineAsync(XmlReader reader)
        {
            EpubSpine result = new EpubSpine();
            bool spineFound = await reader.ReadToFollowingAsync("spine", "http://www.idpf.org/2007/opf");
            if (!spineFound)
                throw new Exception("EPUB parsing error: spine declarations not found in the package.");

            if (String.IsNullOrWhiteSpace(reader.GetAttribute("toc")))
                throw new Exception("Incorrect EPUB spine: TOC attribute is missing or empty");
            result.Toc = reader.GetAttribute("toc");

            while (await reader.ReadAsync() && !(reader.NodeType == XmlNodeType.EndElement && reader.LocalName == "spine"))
            {
                if (reader.LocalName.ToLowerInvariant() == "itemref")
                {
                    EpubSpineItemRef spineItemRef = new EpubSpineItemRef();
                    spineItemRef.IsLinear = true;
                    while (reader.MoveToNextAttribute())
                    {
                        switch (reader.LocalName.ToLowerInvariant())
                        {
                            case "idref":
                                spineItemRef.IdRef = reader.Value;
                                break;
                            case "linear":
                                if (reader.Value.ToLowerInvariant() == "no")
                                {
                                    spineItemRef.IsLinear = false;
                                }
                                break;
                        }
                    }
                    result.Add(spineItemRef);
                }
            }
            return result;
        }
Beispiel #8
0
 private static EpubSpine ReadSpine(XmlNode spineNode)
 {
     EpubSpine result = new EpubSpine();
     XmlAttribute tocAttribute = spineNode.Attributes["toc"];
     if (tocAttribute == null || String.IsNullOrWhiteSpace(tocAttribute.Value))
         throw new Exception("Incorrect EPUB spine: TOC is missing");
     result.Toc = tocAttribute.Value;
     foreach (XmlNode spineItemNode in spineNode.ChildNodes)
         if (String.Compare(spineItemNode.LocalName, "itemref", StringComparison.OrdinalIgnoreCase) == 0)
         {
             EpubSpineItemRef spineItemRef = new EpubSpineItemRef();
             XmlAttribute idRefAttribute = spineItemNode.Attributes["idref"];
             if (idRefAttribute == null || String.IsNullOrWhiteSpace(idRefAttribute.Value))
                 throw new Exception("Incorrect EPUB spine: item ID ref is missing");
             spineItemRef.IdRef = idRefAttribute.Value;
             XmlAttribute linearAttribute = spineItemNode.Attributes["linear"];
             spineItemRef.IsLinear = linearAttribute == null || String.Compare(linearAttribute.Value, "no", StringComparison.OrdinalIgnoreCase) != 0;
             result.Add(spineItemRef);
         }
     return result;
 }
Beispiel #9
0
        public static async Task <EpubPackage> ReadPackageAsync(ZipArchive epubArchive, string rootFilePath)
        {
            ZipArchiveEntry rootFileEntry = epubArchive.GetEntry(rootFilePath);

            if (rootFileEntry == null)
            {
                throw new Exception("EPUB parsing error: root file not found in archive.");
            }
            XDocument containerDocument;

            using (Stream containerStream = rootFileEntry.Open())
                containerDocument = await XmlUtils.LoadDocumentAsync(containerStream).ConfigureAwait(false);
            XNamespace  opfNamespace     = "http://www.idpf.org/2007/opf";
            XElement    packageNode      = containerDocument.Element(opfNamespace + "package");
            EpubPackage result           = new EpubPackage();
            string      epubVersionValue = packageNode.Attribute("version").Value;

            if (epubVersionValue == "2.0")
            {
                result.EpubVersion = EpubVersion.EPUB_2;
            }
            else
            if (epubVersionValue == "3.0")
            {
                result.EpubVersion = EpubVersion.EPUB_3;
            }
            else
            {
                throw new Exception(String.Format("Unsupported EPUB version: {0}.", epubVersionValue));
            }
            XElement metadataNode = packageNode.Element(opfNamespace + "metadata");

            if (metadataNode == null)
            {
                throw new Exception("EPUB parsing error: metadata not found in the package.");
            }
            EpubMetadata metadata = ReadMetadata(metadataNode, result.EpubVersion);

            result.Metadata = metadata;
            XElement manifestNode = packageNode.Element(opfNamespace + "manifest");

            if (manifestNode == null)
            {
                throw new Exception("EPUB parsing error: manifest not found in the package.");
            }
            EpubManifest manifest = ReadManifest(manifestNode);

            result.Manifest = manifest;
            XElement spineNode = packageNode.Element(opfNamespace + "spine");

            if (spineNode == null)
            {
                throw new Exception("EPUB parsing error: spine not found in the package.");
            }
            EpubSpine spine = ReadSpine(spineNode);

            result.Spine = spine;
            XElement guideNode = packageNode.Element(opfNamespace + "guide");

            if (guideNode != null)
            {
                EpubGuide guide = ReadGuide(guideNode);
                result.Guide = guide;
            }
            return(result);
        }
Beispiel #10
0
        //Parsing metadata, manifest, spine and guide
        public static async Task <EpubPackage> ReadPackageAsync(ZipArchive epubArchive, string rootFilePath)
        {
            EpubPackage result = new EpubPackage();

            XmlReaderSettings xmlReaderSettings = new XmlReaderSettings
            {
                // XmlResolver = null,
                Async         = true,
                DtdProcessing = DtdProcessing.Ignore
            };

            ZipArchiveEntry rootFileEntry = epubArchive.GetEntry(rootFilePath);

            if (rootFileEntry == null)
            {
                throw new Exception(string.Format("EPUB parsing error: {0} file not found in archive.", rootFilePath));
            }
            //Starting content.opf parsing...
            using (Stream containerStream = rootFileEntry.Open())
            {
                using (XmlReader xmlReader = XmlReader.Create(containerStream, xmlReaderSettings))
                {
                    await xmlReader.ReadToFollowingAsync("package", "http://www.idpf.org/2007/opf");

                    //Trying to get version attribute from <package version=...
                    //Looks like we only need EPUB version data and we don`t care about unique-identifier
                    //if EPUB version is FUBAR then throwing an exeption
                    xmlReader.MoveToAttribute("version");
                    string epubVersionValue = xmlReader.Value;
                    if (epubVersionValue == "2.0")
                    {
                        result.EpubVersion = EpubVersion.EPUB_2;
                    }
                    else
                    if (epubVersionValue == "3.0")
                    {
                        result.EpubVersion = EpubVersion.EPUB_3;
                    }
                    else
                    {
                        throw new Exception(String.Format("Unsupported EPUB version: {0}.", epubVersionValue));
                    }

                    //Reading metadata
                    EpubMetadata metadata = await ReadMetadataAsync(xmlReader, result.EpubVersion);

                    result.Metadata = metadata;
                    //Reading manifest
                    EpubManifest manifest = await ReadManifestAsync(xmlReader);

                    result.Manifest = manifest;
                    //Reading spine
                    EpubSpine spine = await ReadSpineAsync(xmlReader);

                    result.Spine = spine;
                    //Reading guide. And we actually don`t care if it is no present in our EPUB...
                    bool isGuidePresent = await xmlReader.ReadToFollowingAsync("guide", "http://www.idpf.org/2007/opf");

                    if (isGuidePresent)
                    {
                        EpubGuide guide = await ReadGuideAsync(xmlReader);

                        result.Guide = guide;
                    }
                }
            }

            return(result);
        }