/ src / common / FilePreviewCommon / HTMLParsingExtension.cs
HTMLParsingExtension.cs
  1  // Copyright (c) Microsoft Corporation
  2  // The Microsoft Corporation licenses this file to you under the MIT license.
  3  // See the LICENSE file in the project root for more information.
  4  
  5  using Markdig;
  6  using Markdig.Extensions.Figures;
  7  using Markdig.Extensions.Tables;
  8  using Markdig.Renderers;
  9  using Markdig.Renderers.Html;
 10  using Markdig.Syntax;
 11  using Markdig.Syntax.Inlines;
 12  
 13  namespace Microsoft.PowerToys.FilePreviewCommon
 14  {
 15      /// <summary>
 16      /// Callback if extension blocks external images.
 17      /// </summary>
 18      public delegate void ImagesBlockedCallBack();
 19  
 20      /// <summary>
 21      /// Markdig Extension to process html nodes in markdown AST.
 22      /// </summary>
 23      public class HTMLParsingExtension : IMarkdownExtension
 24      {
 25          /// <summary>
 26          /// Callback if extension blocks external images.
 27          /// </summary>
 28          private readonly ImagesBlockedCallBack imagesBlockedCallBack;
 29  
 30          /// <summary>
 31          /// Initializes a new instance of the <see cref="HTMLParsingExtension"/> class.
 32          /// </summary>
 33          /// <param name="imagesBlockedCallBack">Callback function if image is blocked by extension.</param>
 34          /// <param name="filePath">Absolute path of markdown file.</param>
 35          public HTMLParsingExtension(ImagesBlockedCallBack imagesBlockedCallBack, string filePath = "")
 36          {
 37              this.imagesBlockedCallBack = imagesBlockedCallBack;
 38              FilePath = filePath;
 39          }
 40  
 41          /// <summary>
 42          /// Gets or sets path to directory containing markdown file.
 43          /// </summary>
 44          public string FilePath { get; set; }
 45  
 46          /// <inheritdoc/>
 47          public void Setup(MarkdownPipelineBuilder pipeline)
 48          {
 49              if (pipeline != null)
 50              {
 51                  // Make sure we don't have a delegate twice
 52                  pipeline.DocumentProcessed -= PipelineOnDocumentProcessed;
 53                  pipeline.DocumentProcessed += PipelineOnDocumentProcessed;
 54              }
 55          }
 56  
 57          /// <inheritdoc/>
 58          public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
 59          {
 60          }
 61  
 62          /// <summary>
 63          /// Process nodes in markdown AST.
 64          /// </summary>
 65          /// <param name="document">Markdown Document.</param>
 66          public void PipelineOnDocumentProcessed(MarkdownDocument document)
 67          {
 68              foreach (var node in document.Descendants())
 69              {
 70                  if (node is Block)
 71                  {
 72                      if (node is Table)
 73                      {
 74                          node.GetAttributes().AddClass("table table-striped table-bordered");
 75                      }
 76                      else if (node is QuoteBlock)
 77                      {
 78                          node.GetAttributes().AddClass("blockquote");
 79                      }
 80                      else if (node is Figure)
 81                      {
 82                          node.GetAttributes().AddClass("figure");
 83                      }
 84                      else if (node is FigureCaption)
 85                      {
 86                          node.GetAttributes().AddClass("figure-caption");
 87                      }
 88                  }
 89                  else if (node is Inline)
 90                  {
 91                      if (node is LinkInline link)
 92                      {
 93                          if (link.IsImage)
 94                          {
 95                              link.Url = "#";
 96                              link.GetAttributes().AddClass("img-fluid");
 97                              imagesBlockedCallBack();
 98                          }
 99                      }
100                  }
101              }
102          }
103      }
104  }