예제 #1
0
        public static async Task <Epub2Ncx> ReadEpub2NcxAsync(ZipArchive epubArchive, string contentDirectoryPath, EpubPackage package)
        {
            Epub2Ncx result = new Epub2Ncx();
            string   tocId  = package.Spine.Toc;

            if (String.IsNullOrEmpty(tocId))
            {
                return(null);
            }
            EpubManifestItem tocManifestItem = package.Manifest.FirstOrDefault(item => item.Id.CompareOrdinalIgnoreCase(tocId));

            if (tocManifestItem == null)
            {
                throw new Exception($"EPUB parsing error: TOC item {tocId} not found in EPUB manifest.");
            }
            string          tocFileEntryPath = ZipPathUtils.Combine(contentDirectoryPath, tocManifestItem.Href);
            ZipArchiveEntry tocFileEntry     = epubArchive.GetEntry(tocFileEntryPath);

            if (tocFileEntry == null)
            {
                throw new Exception($"EPUB parsing error: TOC file {tocFileEntryPath} not found in archive.");
            }
            if (tocFileEntry.Length > Int32.MaxValue)
            {
                throw new Exception($"EPUB parsing error: TOC file {tocFileEntryPath} is larger than 2 Gb.");
            }
            XDocument containerDocument;

            using (Stream containerStream = tocFileEntry.Open())
            {
                containerDocument = await XmlUtils.LoadDocumentAsync(containerStream).ConfigureAwait(false);
            }
            XNamespace ncxNamespace = "http://www.daisy.org/z3986/2005/ncx/";
            XElement   ncxNode      = containerDocument.Element(ncxNamespace + "ncx");

            if (ncxNode == null)
            {
                throw new Exception("EPUB parsing error: TOC file does not contain ncx element.");
            }
            XElement headNode = ncxNode.Element(ncxNamespace + "head");

            if (headNode == null)
            {
                throw new Exception("EPUB parsing error: TOC file does not contain head element.");
            }
            Epub2NcxHead navigationHead = ReadNavigationHead(headNode);

            result.Head = navigationHead;
            XElement docTitleNode = ncxNode.Element(ncxNamespace + "docTitle");

            if (docTitleNode == null)
            {
                throw new Exception("EPUB parsing error: TOC file does not contain docTitle element.");
            }
            Epub2NcxDocTitle navigationDocTitle = ReadNavigationDocTitle(docTitleNode);

            result.DocTitle   = navigationDocTitle;
            result.DocAuthors = new List <Epub2NcxDocAuthor>();
            foreach (XElement docAuthorNode in ncxNode.Elements(ncxNamespace + "docAuthor"))
            {
                Epub2NcxDocAuthor navigationDocAuthor = ReadNavigationDocAuthor(docAuthorNode);
                result.DocAuthors.Add(navigationDocAuthor);
            }
            XElement navMapNode = ncxNode.Element(ncxNamespace + "navMap");

            if (navMapNode == null)
            {
                throw new Exception("EPUB parsing error: TOC file does not contain navMap element.");
            }
            Epub2NcxNavigationMap navMap = ReadNavigationMap(navMapNode);

            result.NavMap = navMap;
            XElement pageListNode = ncxNode.Element(ncxNamespace + "pageList");

            if (pageListNode != null)
            {
                Epub2NcxPageList pageList = ReadNavigationPageList(pageListNode);
                result.PageList = pageList;
            }
            result.NavLists = new List <Epub2NcxNavigationList>();
            foreach (XElement navigationListNode in ncxNode.Elements(ncxNamespace + "navList"))
            {
                Epub2NcxNavigationList navigationList = ReadNavigationList(navigationListNode);
                result.NavLists.Add(navigationList);
            }
            return(result);
        }
예제 #2
0
 public static List <EpubNavigationItemRef> GetNavigationItems(EpubBookRef bookRef, Epub2Ncx epub2Ncx)
 {
     return(GetNavigationItems(bookRef, epub2Ncx.NavMap));
 }