private void InlineCss(EpubEbook book, HtmlDocument doc, EbookChapter chapter) { var internalStyles = doc.DocumentNode.Descendants("style").ToList(); var body = HtmlHelper.GetBody(doc); foreach (var s in internalStyles) { s.Remove(); body.PrependChild(s); } var externalStyles = doc.DocumentNode .Descendants("link") .Where(p => p.Attributes["rel"].Value.ToLower() == "stylesheet") .Select(p => p.Attributes["href"].Value) .ToList(); foreach (var s in externalStyles) { var style = book.Data.Resources.Css.FirstOrDefault(p => p.FileName == chapter.ResolveRelativePath(s)); if (style != null) { var css = style.TextContent; foreach (var font in book.Data.Resources.Fonts.Union(book.Data.Resources.Other)) { var fontPath = PathHelper.CombinePath(style.FileName, font.FileName); var extractedFontPath = book.Info.GetTempPath(fontPath); css = css.Replace(fontPath, extractedFontPath); } body.PrependChild(HtmlNode.CreateNode("<style>" + css + "</style>")); } } }
private async void SendChapter(EbookChapter chapter, int position = 0, bool lastPage = false, string marker = "") { _currentChapter = _ebook.HtmlFiles.IndexOf(chapter); _bookshelfBook.Spine = _currentChapter; var html = chapter.Content; var bookLoader = EbookFormatHelper.GetBookLoader(_bookshelfBook.Format); var preparedHtml = await bookLoader.PrepareHtml(html, _ebook, chapter); Device.BeginInvokeOnMainThread(() => { SendHtml(preparedHtml, chapter.Title, position, lastPage, marker); SetStatusPanelValues(new Dictionary <StatusPanelItem, object>() { { StatusPanelItem.BookTitle, _ebook.Title }, { StatusPanelItem.BookAuthor, _ebook.Author } }); }); await _ebook.Info.WaitForProcessingToFinish(); Device.BeginInvokeOnMainThread(() => { var(wordsBefore, wordsCurrent, wordsAfter) = _ebook.Info.GetWordCountsAround(chapter); var json = new JObject { { "wordsBefore", wordsBefore }, { "wordsCurrent", wordsCurrent }, { "wordsAfter", wordsAfter } }; WebView.Messages.Send("setChapterInfo", json); }); }
public virtual async Task <string> PrepareHtml(string html, Ebook book, EbookChapter chapter) { return(await Task.Run(() => { var doc = new HtmlDocument(); doc.LoadHtml(html); HtmlHelper.StripHtmlTags(doc, new[] { "script", "style", "iframe" }); return HtmlHelper.GetBody(doc).InnerHtml; })); }
/// <summary> /// Enumerates all img tags and svg.image tags and extracts image paths. Each image is /// converted to base64, and inserted directly into the HTML code. /// </summary> /// <param name="data"></param> /// <param name="doc"></param> /// <param name="chapter"></param> /// <returns></returns> private void InlineImages(EpubEbook book, HtmlDocument doc, EbookChapter chapter) { var imageData = book.Data.Resources.Images.ToDictionary(k => k.FileName, v => v); // Find all img and image nodes, and extract their source path var images = doc.DocumentNode.Descendants("img") .Select(p => new { Node = p, Src = p.Attributes.FirstOrDefault(c => c.Name == "src") }) .Union(doc.DocumentNode.Descendants("image") .Select(p => new { Node = p, Src = p.Attributes.FirstOrDefault(c => c.Name == "xlink:href") })) // Remove images without source .Where(p => p.Src != null) // Convert the relative HTML path to an absolute (inside local folder) path .Select(p => new { p.Node, p.Src, Path = chapter.ResolveRelativePath(p.Src.Value) }) // Group by image path to avoid loading and transferring the same image more than once .GroupBy(p => p.Path); foreach (var image in images) { var imgData = imageData[image.Key]; //var base64 = Base64Helper.Encode(imgData.Content); //var ctype = imgData.ContentType.ToString().ToLower().Replace("image", "image/"); // From enum "ImageJpeg" to "image/jpeg". foreach (var element in image) { //element.Node.Attributes["src"].Value = $"data:{ctype};base64,{base64}"; var tempPath = book.Info.GetTempPath(imgData.FileName); if (!System.IO.File.Exists(tempPath)) { var dir = Path.GetDirectoryName(tempPath); Directory.CreateDirectory(dir); System.IO.File.WriteAllBytes(tempPath, imgData.Content); } if (element.Node.Attributes.Contains("src")) { element.Node.Attributes["src"].Value = tempPath; } if (element.Node.Attributes.Contains("xlink:href")) { element.Node.Attributes["xlink:href"].Value = tempPath; } } } }
public async Task <string> PrepareHtml(string html, Ebook book, EbookChapter chapter) { return(await Task.Run(() => { var doc = new HtmlDocument(); doc.LoadHtml(html); HtmlHelper.StripHtmlTags(doc, "iframe"); var data = ((EpubEbook)book); InlineCss(data, doc, chapter); InlineImages(data, doc, chapter); return HtmlHelper.GetBody(doc).InnerHtml; })); }
public void ResolveRelativePathTests() { var chapter = new EbookChapter("", "", "Text/text0001.html"); Assert.AreEqual("Text/text0002.html", chapter.ResolveRelativePath("text0002.html")); Assert.AreEqual("text0002.html", chapter.ResolveRelativePath("../text0002.html")); Assert.AreEqual("Text/text0002.html", chapter.ResolveRelativePath("../Text/text0002.html")); Assert.AreEqual("Imgs/cover.png", chapter.ResolveRelativePath("../Imgs/cover.png")); Assert.AreEqual("cover.png", chapter.ResolveRelativePath("../cover.png")); chapter = new EbookChapter("", "", "text0001.html"); Assert.AreEqual("text0002.html", chapter.ResolveRelativePath("text0002.html")); Assert.AreEqual("text0002.html", chapter.ResolveRelativePath("../text0002.html")); Assert.AreEqual("Text/text0002.html", chapter.ResolveRelativePath("../Text/text0002.html")); Assert.AreEqual("Imgs/cover.png", chapter.ResolveRelativePath("../Imgs/cover.png")); Assert.AreEqual("cover.png", chapter.ResolveRelativePath("../cover.png")); Assert.AreEqual("cover.png", chapter.ResolveRelativePath("/cover.png")); }
private void OpenEpub() { EpubBook epub = EpubReader.OpenBook(FilePath); this.Title = epub.Title; this.Author = epub.Author; this.PathToCoverImage = Path.GetFileName(FilePath).Split('.')[0] + ".png"; this.PathToCoverImage = PathToCoverImage.Replace(' ', '_').Replace('-', '_'); this.PathToCoverImage = System.Web.HttpContext.Current.Server.MapPath("~/Images/" + PathToCoverImage); Bitmap bmp = new Bitmap(epub.CoverImage); bmp.Save(this.PathToCoverImage); this.PathToCoverImage = Path.GetFileName(PathToCoverImage); //epub.CoverImage.Save(PathToCoverImage); foreach (EpubChapter chapter in epub.Chapters) { EbookChapter chptr = new EbookChapter(); chptr.Title = chapter.Title; chptr.ChapterContent = chapter.HtmlContent; this.Chapters.Add(chptr); } if (epub.Chapters.Count <= 1) { foreach (var chapter in epub.Content.Html) { EbookChapter chptr = new EbookChapter(); chptr.Title = ""; chptr.ChapterContent = chapter.Value.Content; this.Chapters.Add(chptr); } } }
public override async Task <string> PrepareHtml(string html, Ebook book, EbookChapter chapter) { html = $"<body><p>{html}</p></body>".Replace("\n", "</p><p>"); return(await base.PrepareHtml(html, book, chapter)); }
public ChapterData(EbookChapter chapter) { Title = chapter.Title; Href = chapter.Href; (Words, Letters) = chapter.GetStatistics(); }
private void ChapterList_OnChapterClicked(object sender, EbookChapter e) { _chapterListPopup.Hide(); LoadChapter(e.Href); }