Advertisement
Guest User

Untitled

a guest
Nov 22nd, 2014
167
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.20 KB | None | 0 0
  1. using HtmlAgilityPack;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Diagnostics;
  5. using System.IO;
  6. using System.Net;
  7. using System.Reflection;
  8. using System.Text;
  9. using System.Text.RegularExpressions;
  10. using System.Threading.Tasks;
  11. using Windows.Data.Xml.Dom;
  12. using Windows.Data.Xml.Xsl;
  13. using Windows.Foundation;
  14. using Windows.Storage;
  15. using Windows.Storage.Streams;
  16. using Windows.UI.Xaml;
  17. using Windows.UI.Xaml.Controls;
  18. using Windows.UI.Xaml.Documents;
  19. using Windows.UI.Xaml.Markup;
  20.  
  21. namespace AVIS_Toscana.Common
  22. {
  23. /// <summary>
  24. /// Usage:
  25. /// 1) In a XAML file, declare the above namespace, e.g.:
  26. /// xmlns:common="using:AVIS_Toscana.Common"
  27. ///
  28. /// 2) In RichTextBlock controls, set or databind the Html property, e.g.:
  29. ///
  30. /// <RichTextBlock common:Properties.Html="{Binding ...}"/>
  31. ///
  32. /// or
  33. ///
  34. /// <RichTextBlock>
  35. /// <common:Properties.Html>
  36. /// <![CDATA[
  37. /// <p>This is a list:</p>
  38. /// <ul>
  39. /// <li>Item 1</li>
  40. /// <li>Item 2</li>
  41. /// <li>Item 3</li>
  42. /// </ul>
  43. /// ]]>
  44. /// </common:Properties.Html>
  45. /// </RichTextBlock>
  46. /// </summary>
  47. public class Properties : DependencyObject
  48. {
  49. public static readonly DependencyProperty HtmlProperty =
  50. DependencyProperty.RegisterAttached("Html", typeof(string), typeof(Properties), new PropertyMetadata(null, HtmlChanged));
  51.  
  52. public static void SetHtml(DependencyObject obj, string value)
  53. {
  54. obj.SetValue(HtmlProperty, value);
  55. }
  56.  
  57. public static string GetHtml(DependencyObject obj)
  58. {
  59. return (string)obj.GetValue(HtmlProperty);
  60. }
  61.  
  62. private static async void HtmlChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  63. {
  64. // Get the target RichTextBlock
  65. RichTextBlock richText = d as RichTextBlock;
  66. if (richText == null) return;
  67.  
  68. // Wrap the value of the Html property in a div and convert it to a new RichTextBlock
  69. string xhtml = string.Format("<div>{0}</div>", e.NewValue as string);
  70. RichTextBlock newRichText = null;
  71. if (Windows.ApplicationModel.DesignMode.DesignModeEnabled)
  72. {
  73. // In design mode we swallow all exceptions to make editing more friendly
  74. string xaml = "";
  75. try {
  76. xaml = await ConvertHtmlToXamlRichTextBlock(xhtml);
  77. newRichText = (RichTextBlock)XamlReader.Load(xaml);
  78. }
  79. catch (Exception ex) {
  80. string errorxaml = string.Format(@"
  81. <RichTextBlock
  82. xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
  83. xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  84. >
  85. <Paragraph>An exception occurred while converting HTML to XAML: {0}</Paragraph>
  86. <Paragraph />
  87. <Paragraph>HTML:</Paragraph>
  88. <Paragraph>{1}</Paragraph>
  89. <Paragraph />
  90. <Paragraph>XAML:</Paragraph>
  91. <Paragraph>{2}</Paragraph>
  92. </RichTextBlock>",
  93. ex.Message,
  94. EncodeXml(xhtml),
  95. EncodeXml(xaml)
  96. );
  97. newRichText = (RichTextBlock)XamlReader.Load(errorxaml);
  98. } // Display a friendly error in design mode.
  99. }
  100. else
  101. {
  102. // When not in design mode, we let the application handle any exceptions
  103. string xaml = await ConvertHtmlToXamlRichTextBlock(xhtml);
  104. newRichText = (RichTextBlock)XamlReader.Load(xaml);
  105. }
  106.  
  107. // Move the blocks in the new RichTextBlock to the target RichTextBlock
  108. richText.Blocks.Clear();
  109. if (newRichText != null)
  110. {
  111. for (int i = newRichText.Blocks.Count - 1; i >= 0; i--)
  112. {
  113. Block b = newRichText.Blocks[i];
  114. newRichText.Blocks.RemoveAt(i);
  115. richText.Blocks.Insert(0, b);
  116. }
  117. }
  118. }
  119.  
  120. private static string EncodeXml(string xml)
  121. {
  122. string encodedXml = xml.Replace("&", "&amp;").Replace("<", "&lt;").Replace(">", "&gt;").Replace("\"", "&quot;").Replace("'", "&apos;");
  123. return encodedXml;
  124. }
  125.  
  126. private static XsltProcessor Html2XamlProcessor;
  127.  
  128. private static async Task<string> ConvertHtmlToXamlRichTextBlock(string htmlString)
  129. {
  130. // Decode HTML string
  131. htmlString = WebUtility.HtmlDecode(htmlString);
  132.  
  133. // Move images in paragraph
  134. htmlString = Regex.Replace(htmlString, "<img(.*?)/>", "</p><p><img$1/></p><p>");
  135.  
  136. // Create HTML document
  137. HtmlDocument htmlDocument = new HtmlDocument();
  138. htmlDocument.LoadHtml(htmlString);
  139. htmlDocument.OptionOutputAsXml = true;
  140.  
  141. // Remove "porcheria"
  142. foreach (var element in htmlDocument.DocumentNode.Descendants())
  143. {
  144. if (element.Name == "img" &&
  145. element.Attributes["class"] != null &&
  146. element.Attributes["class"].Value.Contains("skype"))
  147. {
  148. element.Name = "span";
  149. }
  150. }
  151.  
  152. // Export document as XML
  153. MemoryStream memoryStream = new MemoryStream();
  154. htmlDocument.Save(memoryStream);
  155.  
  156. memoryStream.Position = 0;
  157. StreamReader streamReader = new StreamReader(memoryStream);
  158. string xmlString = streamReader.ReadToEnd();
  159.  
  160. // Create style processor
  161. if (Html2XamlProcessor == null)
  162. {
  163. // Read XSLT. In design mode we cannot access the xslt from the file system (with Build Action = Content),
  164. // so we use it as an embedded resource instead:
  165. Assembly assembly = typeof(Properties).GetTypeInfo().Assembly;
  166. using (Stream stream = assembly.GetManifestResourceStream("AVIS_Toscana.Common.RichTextBlockHtml2Xaml.xslt"))
  167. {
  168. StreamReader reader = new StreamReader(stream);
  169. string content = await reader.ReadToEndAsync();
  170. XmlDocument html2XamlXslDoc = new XmlDocument();
  171. html2XamlXslDoc.LoadXml(content);
  172. Html2XamlProcessor = new XsltProcessor(html2XamlXslDoc);
  173. }
  174. }
  175.  
  176. // Apply XSLT to XML
  177. XmlDocument doc = new XmlDocument();
  178. doc.LoadXml(xmlString);
  179. string xaml = Html2XamlProcessor.TransformToString(doc);
  180. return xaml;
  181. }
  182.  
  183.  
  184. }
  185. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement