123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text.RegularExpressions;
- using HtmlAgilityPack;
- namespace InABox.Core
- {
- public static class HTMLUtils
- {
-
- /// <summary>
- /// Takes a HTML Snippet and converts it to full HTML.
- /// This is used to convert Fast-Reports "html-enabled" text to Syncfusion RichTextEditor html.
- /// </summary>
- /// <param name="text">The html snippet (no <head> or <body> tags, paragraphs represented by line breaks</param>
- /// <returns>Properly formed HTM suitable for editing</returns>
- public static string TextToHtml(string text)
- {
- var result = text;
- if (!result.Contains("<html>"))
- {
- var lines = result.Split("\n").Select(l => $"<p>{(string.IsNullOrWhiteSpace(l) ? " " : l)}</p>").ToList();
- while (string.Equals(lines.LastOrDefault(),$"<p> </p>"))
- lines.RemoveAt(lines.Count-1);
- result = $"<html><body>{string.Join("\n",lines)}</body></html>";
- }
- var doc = new HtmlDocument();
- doc.LoadHtml(result);
- HtmlNode? head = null;
- var htmlnode = doc.DocumentNode.SelectSingleNode("//html");
- if (!htmlnode.ChildNodes.Any(x => string.Equals(x.Name, "head", StringComparison.CurrentCultureIgnoreCase)))
- {
- head = doc.CreateElement("head");
- htmlnode.PrependChild(head);
- }
- head = doc.DocumentNode.SelectSingleNode("//head");
- if (head != null)
- {
- HtmlNode? style = null;
- if (!head.ChildNodes.Any(x =>
- string.Equals(x.Name, "style", StringComparison.CurrentCultureIgnoreCase)))
- {
- style = doc.CreateElement("style");
- head.PrependChild(style);
- }
- else
- style = head.ChildNodes["style"];
- style.InnerHtml = "p { margin: 0px 0px 0px 0px; }";
- }
- return doc.DocumentNode.OuterHtml;
- }
- /// <summary>
- /// Converts HTML data to Fast-Reports compatible "html-enabled" text
- /// Will dump tags that Fast-Reports cannot display
- /// </summary>
- /// <param name="html">The HTML data to be processed</param>
- /// <returns>Text Suitable for printing using Fast-Reports</returns>
- public static string HtmlToText(string html)
- {
- Dictionary<string, string> _replacements = new Dictionary<string, string>()
- {
- { "\n", "" },
- { "\r", "" },
- { "<p[^>]*>", "" },
- { "</p[^>]*>", "\r\n" },
- };
-
- var doc = new HtmlDocument();
- doc.LoadHtml(html);
- ProcessNode(doc.DocumentNode, (n) => ReplaceAttribute(n, "font-style","italic", "i"));
- ProcessNode(doc.DocumentNode, (n) => ReplaceAttribute(n, "text-decoration","underline", "u"));
- ProcessNode(doc.DocumentNode, (n) => ReplaceAttribute(n, "font-weight","bold", "b"));
- ProcessNode(doc.DocumentNode, (n) => ReplaceAttribute(n, "font-size","(.*?)", ""));
- ProcessNode(doc.DocumentNode, (n) => ReplaceAttribute(n, "font-family","(.*?)", ""));
- ProcessNode(doc.DocumentNode, (n) => ReplaceAttribute(n, "background","(.*?)", ""));
-
- string result = doc.DocumentNode.SelectSingleNode("//body").InnerHtml;
-
- foreach (var _key in _replacements.Keys)
- result = Regex.Replace(result, _key, _replacements[_key]);
- var lines = result.Split("\r\n").ToList();
- while (string.IsNullOrWhiteSpace(lines.LastOrDefault()))
- lines.RemoveAt(lines.Count-1);
- return string.Join("\r\n", lines);
- }
-
- private static void ProcessNode(HtmlNode node, Action<HtmlNode> action)
- {
- if (node.Name.ToLower() == "span")
- action(node);
- foreach (var _child in node.ChildNodes)
- ProcessNode(_child,action);
- }
-
- private static void ReplaceAttribute(HtmlNode node, string attribute, string value, string tag)
- {
- var _value = $"{attribute}:{value};";
- var _style = node.Attributes.Contains("style") ? node.Attributes["style"] : null;
- if (_style != null)
- {
- var _oldvalue = _style.Value;
- _style.Value = Regex.Replace(_style.Value, _value, "");
- if (!string.Equals(_style.Value, _oldvalue))
- {
- if (string.IsNullOrWhiteSpace(_style.Value))
- node.Attributes.Remove("style");
- if (!string.IsNullOrWhiteSpace(tag))
- {
- var text = node.OuterHtml;
- node.Name = tag;
- node.Attributes.RemoveAll();
- node.InnerHtml = text;
- }
- }
- }
- }
-
- }
- }
|