public string ConvertToHtml(string markDownText, string filepath)
        {
            var pipeline = new MarkdownPipelineBuilder().UseAdvancedExtensions().Build();

            pipeline.PreciseSourceLocation = true;
            try
            {
                htmlRenderer.BaseUrl = new Uri(filepath);
            }
            catch (Exception e)
            {
            }
            sb.Clear();

            var document = Markdown.Parse(markDownText, pipeline, null);

            SetLineNoAttributeOnAllBlocks(document);

            pipeline.Setup(htmlRenderer);
            htmlRenderer.Render(document);

            htmlWriter.Flush();
            var result = sb.ToString();

            return(result);
        }
        public static (Dictionary <string, string> Meta, string Content) ParseDemoDoc(string input)
        {
            var pipeline = new MarkdownPipelineBuilder()
                           .UseYamlFrontMatter()
                           .Build();

            StringWriter writer   = new StringWriter();
            var          renderer = new HtmlRenderer(writer);

            pipeline.Setup(renderer);

            MarkdownDocument document = Markdown.Parse(input, pipeline);
            var yamlBlock             = document.Descendants <YamlFrontMatterBlock>().FirstOrDefault();

            Dictionary <string, string> meta = null;

            if (yamlBlock != null)
            {
                string yaml = input.Substring(yamlBlock.Span.Start, yamlBlock.Span.Length).Trim('-');
                meta = new Deserializer().Deserialize <Dictionary <string, string> >(yaml);
            }

            renderer.Render(document);
            writer.Flush();
            string html = writer.ToString();

            return(meta, html);
        }
        public static (Dictionary <string, string> Meta, string Desc, string ApiDoc) ParseDemoDoc(string input)
        {
            var pipeline = new MarkdownPipelineBuilder()
                           .UseYamlFrontMatter()
                           .UsePipeTables()
                           .Build();

            var document  = Markdown.Parse(input, pipeline);
            var yamlBlock = document.Descendants <YamlFrontMatterBlock>().FirstOrDefault();

            Dictionary <string, string> meta = null;

            if (yamlBlock != null)
            {
                var yaml = input.Substring(yamlBlock.Span.Start, yamlBlock.Span.Length).Trim('-');
                meta = new Deserializer().Deserialize <Dictionary <string, string> >(yaml);
            }

            var isAfterApi = false;
            var descPart   = "";
            var apiPart    = "";

            for (var i = yamlBlock?.Line ?? 0; i < document.Count; i++)
            {
                var block = document[i];
                if (block is YamlFrontMatterBlock)
                {
                    continue;
                }

                if (block is HeadingBlock heading && heading.Level == 2 && heading.Inline.FirstChild.ToString() == "API")
                {
                    isAfterApi = true;
                }

                using var writer = new StringWriter();
                var renderer = new HtmlRenderer(writer);
                pipeline.Setup(renderer);

                var blockHtml = renderer.Render(block);

                if (!isAfterApi)
                {
                    descPart += blockHtml;
                }
                else
                {
                    apiPart += blockHtml;
                }
            }

            return(meta, descPart, apiPart);
        }
Exemple #4
0
        protected string GetMarkdownRendererFromMarkdownDocument(MarkdownDocument document)
        {
            var pipeline = new MarkdownPipelineBuilder().Build();

            var writer   = new StringWriter();
            var renderer = new Markdig.Renderers.HtmlRenderer(writer);

            pipeline.Setup(renderer);

            renderer.Render(document);

            writer.Flush();
            return(writer.ToString());
        }
        private static T UseMarkdown <T>(this T kernel)
            where T : Kernel
        {
            var pipeline = new MarkdownPipelineBuilder()
                           .UseMathematics()
                           .UseAdvancedExtensions()
                           .Build();

            kernel.AddDirective(new Command("#!markdown", "Convert the code that follows from Markdown into HTML")
            {
                Handler = CommandHandler.Create((InvocationContext cmdLineContext) =>
                {
                    var context = cmdLineContext.GetService <KernelInvocationContext>();

                    if (context.Command is SubmitCode submitCode)
                    {
                        var markdown = submitCode.Code
                                       .Replace("#!markdown", "")
                                       .Trim();

                        var document = Markdown.Parse(
                            markdown,
                            pipeline);

                        string html;

                        using (var writer = new StringWriter())
                        {
                            var renderer = new HtmlRenderer(writer);
                            pipeline.Setup(renderer);
                            renderer.Render(document);
                            html = writer.ToString();
                        }

                        context.Publish(
                            new DisplayedValueProduced(
                                html,
                                context.Command,
                                new[]
                        {
                            new FormattedValue("text/html", html)
                        }));

                        context.Complete(submitCode);
                    }

                    return(Task.CompletedTask);
                })
            });
Exemple #6
0
        /// <summary>
        /// Render the Markdown data to generic HTML.
        /// </summary>
        /// <param name="markup">The Markdown to mark up.</param>
        /// <returns>Generic HTML markup.</returns>
        private static string Render(string markup)
        {
            var sb       = new StringBuilder();
            var sw       = new StringWriter(sb);
            var render   = new HtmlRenderer(sw);
            var pipeline = new MarkdownPipelineBuilder()
                           .Build();

            pipeline.Setup(render);
            var doc = MarkdownParser.Parse(markup);

            render.Render(doc);
            sw.Flush();
            return(sb.ToString());
        }
            static string ToMarkdown(IEnumerable <Block> blocks)
            {
                var writer   = new StringWriter();
                var renderer = new NormalizeRenderer(writer);
                var pipeline = new MarkdownPipelineBuilder().Build();

                pipeline.Setup(renderer);
                foreach (var block in blocks)
                {
                    renderer.Render(block);
                }
                // We convert \n to \r because the YAML serialization will eventually
                // output \n\n for \n, but \r\n for \r.
                return(writer.ToString().TrimEnd().Replace('\n', '\r'));
            }
Exemple #8
0
        public void Test3()
        {
            var pipeline = new MarkdownPipelineBuilder()
                           .Use <VariableExtension>()
                           .Build();

            var doc = MarkdownParser.Parse("# Hallo\r\n## Test\r\n$(Test)\r\nTest", pipeline);

            var adf      = new AdfDocument();
            var renderer = new AdfRenderer(adf);

            pipeline.Setup(renderer);

            renderer.Render(doc);
        }
Exemple #9
0
        public void CorrectlyIdentifiesParserMatch(string markdown)
        {
            var _pipeline = new MarkdownPipelineBuilder()
                            .UseEmbeddedGists(config =>
            {
                config.UseMockRender(_renderFragment);
                config.AddBaseUrl(_alternateBaseUrl);
            }).Build();

            _pipeline.Setup(_renderer);

            var _result = Markdown.ToHtml(markdown, _pipeline);

            _result.Trim().Should().Be($"<p>{_renderFragment}</p>");
        }
        // notes may contain html and markdown, so to include:
        // 1. Convert html into markdown
        // 2. Parse markdown into ast
        // 3. Normalize headings
        // 4. Convert ast into markdown text
        // 5. Add markdown text to stream
        public string Normalize(string text)
        {
            string           markdownText = _converter.Convert(text);
            MarkdownDocument markdown     = Markdown.Parse(markdownText);

            using (var writer = new StringWriter())
            {
                var pipeline = new MarkdownPipelineBuilder().Build();
                pipeline.Extensions.AddIfNotAlready <SoftlineBreakAsHardlineExtension>();
                var renderer = new NormalizeRenderer(writer);
                pipeline.Setup(renderer);
                renderer.Render(markdown);
                writer.Flush();
                return(writer.ToString());
            }
        }
Exemple #11
0
        private static async Task <string> Render(
            PublishFormat format,
            MarkdownDocument document,
            Dictionary <string, string> outputsBySessionName)
        {
            MarkdownPipeline  pipeline;
            IMarkdownRenderer renderer;
            var writer = new StringWriter();

            switch (format)
            {
            case PublishFormat.Markdown:
                pipeline = new MarkdownPipelineBuilder()
                           .UseNormalizeCodeBlockAnnotations(outputsBySessionName)
                           .Build();
                var normalizeRenderer = new NormalizeRenderer(writer);
                normalizeRenderer.Writer.NewLine = "\n";
                renderer = normalizeRenderer;
                break;

            case PublishFormat.HTML:
                pipeline = new MarkdownPipelineBuilder()
                           .UseCodeBlockAnnotations(inlineControls: false)
                           .Build();
                renderer = new HtmlRenderer(writer);
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(format), format, null);
            }

            pipeline.Setup(renderer);

            var blocks = document
                         .OfType <AnnotatedCodeBlock>()
                         .OrderBy(c => c.Order)
                         .ToList();

            await Task.WhenAll(blocks.Select(b => b.InitializeAsync()));

            renderer.Render(document);
            writer.Flush();

            var rendered = writer.ToString();

            return(rendered);
        }
Exemple #12
0
        public static void TestSpec(Func <string, string> linkRewriter, string markdown, string expectedLink)
        {
            var pipeline = new MarkdownPipelineBuilder().Build();

            var writer   = new StringWriter();
            var renderer = new HtmlRenderer(writer);

            renderer.LinkRewriter = linkRewriter;
            pipeline.Setup(renderer);

            var document = MarkdownParser.Parse(markdown, pipeline);

            renderer.Render(document);
            writer.Flush();

            Assert.That(writer.ToString(), Contains.Substring("=\"" + expectedLink + "\""));
        }
Exemple #13
0
        public void CorrectlyIgnoresStandardLink(string markdown)
        {
            var _pipeline = new MarkdownPipelineBuilder()
                            .UseAutoLinks()
                            .UseEmbeddedGists(config =>
            {
                config.UseMockRender(_renderFragment);
                config.AddBaseUrl(_alternateBaseUrl);
            }).Build();

            _pipeline.Setup(_renderer);

            var _result = Markdown.ToHtml(markdown, _pipeline);

            _result.Trim().Should().NotBe($"<p>{_renderFragment}</p>");
            _result.Trim().Should().NotContain(_renderFragment);
        }
        protected string ToPlainText(string markdown)
        {
            var writer   = new StringWriter();
            var pipeline = new MarkdownPipelineBuilder().Build();

            // We override the renderer with our own writer
            var renderer = new PlainTextRenderer(writer);

            pipeline.Setup(renderer);

            var document = Markdown.Parse(markdown, pipeline);

            renderer.Render(document);
            writer.Flush();

            return(writer.ToString());
        }
Exemple #15
0
        /*
         * public static Item ToItem(string md)
         * {
         *  var pipeline = new MarkdownPipelineBuilder().UsePipeTables().Build();
         *  var document = MarkdownParser.Parse(md, pipeline);
         *
         *  var enumerator = document.GetEnumerator();
         *  try
         *  {
         *      enumerator.MoveNext();
         *      while (enumerator.Current != null)
         *      {
         *          var block = enumerator.Current;
         *
         *          if (block is HtmlBlock)
         *          {
         *              if (block.IsNewItem())
         *              {
         *                  var item = ParseItem(ref enumerator);
         *                  return item;
         *              }
         *          }
         *          enumerator.MoveNext();
         *      }
         *
         *  }
         *  finally
         *  {
         *      enumerator.Dispose();
         *  }
         *  return null;
         * }
         *
         * public static Item ParseItem(ref ContainerBlock.Enumerator enumerator)
         * {
         *  var currentItem = enumerator.Current.GetNewItem();
         *
         *  if (currentItem != null)
         *  {
         *      enumerator.MoveNext();
         *      while (enumerator.Current != null)
         *      {
         *          var block = enumerator.Current;
         *
         *          if (block is HtmlBlock)
         *          {
         *              if (block.IsClosingItem())
         *              {
         *                  return currentItem;
         *              }
         *              else if (block.IsNewItem())
         *              {
         *                  var subItem = ParseItem(ref enumerator);
         *
         *                  var propertyName = subItem.GetType().Name;
         *
         *                  if (currentItem.GetType().GetProperty(propertyName) != null)
         *                  {
         *                      PropertyInfo prop = currentItem.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance);
         *                      if (null != prop && prop.CanWrite)
         *                      {
         *                          prop.SetValue(currentItem, subItem, null);
         *                      }
         *                  }
         *                  else if (currentItem is Items)
         *                  {
         *                      var items = currentItem as Items;
         *                      items.Add(subItem);
         *                  }
         *              }
         *          }
         *
         *          else // if (block is ContainerBlock)
         *          {
         *              ParseItemProperties(currentItem, block);
         *          }
         *
         *          currentItem.Markdown += enumerator.Current.ToMarkdownString();
         *
         *          enumerator.MoveNext();
         *      }
         *  }
         *
         *  return currentItem;
         * }
         *
         * public static void ParseItemProperties(Item item, Block block)
         * {
         *  switch(block)
         *  {
         *      case Markdig.Extensions.Tables.Table table:
         *          ParseItemProperties(item, table);
         *          break;
         *      case ContainerBlock blocks:
         *          ParseItemProperties(item, blocks);
         *          break;
         *      case LeafBlock leaf:
         *          ParseItemProperties(item, leaf.Inline);
         *          break;
         *  }
         * }
         *
         * public static void ParseItemProperties(Item item, ContainerBlock blocks)
         * {
         *  foreach(var block in blocks)
         *  {
         *      ParseItemProperties(item, block);
         *  }
         * }
         *
         * public static void ParseItemProperties(Item item, ContainerInline inlines)
         * {
         *  if(inlines == null)
         *  {
         *      return;
         *  }
         *  PropertyInfo prop = null;
         *  foreach (var inline in inlines)
         *  {
         *      if(inline is HtmlInline)
         *      {
         *          var tag = (inline as HtmlInline).Tag;
         *          if(tag == "<!--br-->" || tag =="<br>")
         *          {
         *
         *          }
         *          else if (tag.StartsWith("<!--/"))
         *          {
         *              prop = null;
         *          }
         *          else if (tag.StartsWith("<!--") && !tag.StartsWith("<!--/"))
         *          {
         *              var propertyName = tag.Substring(4, tag.Length - 7);
         *              prop = item.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance);
         *          }
         *      }
         *      else
         *      {
         *          if (null != prop && prop.CanWrite)
         *          {
         *              prop.SetValue(item, inline.ToMarkdownString(), null);
         *          }
         *      }
         *  }
         * }
         *
         *
         *
         * public static bool IsNewItem(this Block block)
         * {
         *  var htmlBlock = block as HtmlBlock;
         *  if (htmlBlock.Type == HtmlBlockType.Comment)
         *  {
         *      var tag = htmlBlock.Lines.Lines.FirstOrDefault().Slice.ToString();
         *      if (!string.IsNullOrEmpty(tag) && tag != "<!--br-->" && tag != "<br>")
         *      {
         *          if (tag.StartsWith("<!--") && !tag.StartsWith("<!--/"))
         *          {
         *              return true;
         *          }
         *      }
         *  }
         *  return false;
         * }
         *
         * public static bool IsClosingItem(this Block block)
         * {
         *  var htmlBlock = block as HtmlBlock;
         *  if (htmlBlock.Type == HtmlBlockType.Comment)
         *  {
         *      var tag = htmlBlock.Lines.Lines.FirstOrDefault().Slice.ToString();
         *      if (!string.IsNullOrEmpty(tag) && tag != "<!--br-->" && tag != "<br>")
         *      {
         *          if (tag.StartsWith("<!--/"))
         *          {
         *              return true;
         *          }
         *      }
         *  }
         *  return false;
         * }
         *
         * public static Item GetNewItem(this Block block)
         * {
         *  var htmlBlock = block as HtmlBlock;
         *  if (htmlBlock.Type == HtmlBlockType.Comment)
         *  {
         *      var tag = htmlBlock.Lines.Lines.FirstOrDefault().Slice.ToString();
         *      if (!string.IsNullOrEmpty(tag) && tag != "<!--br-->" && tag != "<br>")
         *      {
         *          if (tag.StartsWith("<!--") && !tag.StartsWith("<!--/"))
         *          {
         *              var name = $"AideDeJeuLib.{tag.Substring(4, tag.Length - 7)}, AideDeJeu";
         *              var type = Type.GetType(name);
         *              var instance = Activator.CreateInstance(type) as Item;
         *              return instance;
         *          }
         *      }
         *  }
         *  return null;
         * }
         */

        /*
         * public static Item ToItem(string md)
         * {
         *  var pipeline = new MarkdownPipelineBuilder().UsePipeTables().Build();
         *  var document = MarkdownParser.Parse(md, pipeline);
         *
         *  var enumerator = document.GetEnumerator();
         *  try
         *  {
         *      enumerator.MoveNext();
         *      while (enumerator.Current != null)
         *      {
         *          var block = enumerator.Current;
         *
         *          if (enumerator.Current is ParagraphBlock)
         *          {
         *              if(block.IsNewItem())
         *              {
         *                  var item = block.GetNewItem();
         *                  item.Parse(ref enumerator);
         *                  return item;
         *              }
         *          }
         *          enumerator.MoveNext();
         *      }
         *
         *  }
         *  finally
         *  {
         *      enumerator.Dispose();
         *  }
         *  return null;
         * }
         *
         * public static bool IsNewItem(this Block block)
         * {
         *  var paragraphBlock = block as ParagraphBlock;
         *  var linkInline = paragraphBlock?.Inline?.FirstChild as LinkInline;
         *  if (linkInline != null)
         *  {
         *      var label = linkInline.Label;
         *      var title = linkInline.Title;
         *      if (title == string.Empty && label != string.Empty)
         *      {
         *          return true;
         *      }
         *  }
         *  return false;
         * }
         *
         * public static bool IsClosingItem(this Block block)
         * {
         *  var paragraphBlock = block as ParagraphBlock;
         *  var linkInline = paragraphBlock?.Inline?.FirstChild as LinkInline;
         *  if (linkInline != null)
         *  {
         *      var label = linkInline.Label;
         *      var title = linkInline.Title;
         *      if (title == string.Empty && label == string.Empty)
         *      {
         *          return true;
         *      }
         *  }
         *  return false;
         * }
         *
         * public static Item GetNewItem(this Block block)
         * {
         *  var paragraphBlock = block as ParagraphBlock;
         *  var linkInline = paragraphBlock?.Inline?.FirstChild as LinkInline;
         *  if (linkInline != null)
         *  {
         *      var label = linkInline.Label;
         *      var title = linkInline.Title;
         *      var url = linkInline.Url;
         *      if (title == string.Empty)
         *      {
         *          var name = $"AideDeJeuLib.{label}, AideDeJeu";
         *          var type = Type.GetType(name);
         *          var instance = Activator.CreateInstance(type) as Item;
         *          return instance;
         *      }
         *  }
         *  return null;
         * }
         */


        public static string ToMarkdownString(this Block block)
        {
            var pipeline = new MarkdownPipelineBuilder()
                           .UsePipeTables()
                           .Build();

            using (var writer = new StringWriter())
            {
                var renderer = new NormalizeRenderer(writer);
                renderer.ObjectRenderers.Remove(renderer.ObjectRenderers.FirstOrDefault(i => i is LinkInlineRenderer));
                renderer.ObjectRenderers.Add(new LinkInlineRendererEx());
                renderer.ObjectRenderers.Add(new TableRenderer());
                pipeline.Setup(renderer);

                renderer.Render(block);
                return(writer.ToString());
            }
        }
Exemple #16
0
        private void Convert(FileInfo mdFile)
        {
            var name    = mdFile.Directory.Name;
            var htmlDir = Path.Combine(_config.OutputDirectory, name);

            if (!Directory.Exists(htmlDir))
            {
                Directory.CreateDirectory(htmlDir);
            }
            using (var reader = mdFile.OpenText())
            {
                var pipeline = new MarkdownPipelineBuilder().UseAdvancedExtensions().UseYamlFrontMatter().Build();
                var doc      = Markdown.Parse(reader.ReadToEnd(), pipeline);
                // Actual HTML conversion now?
                var htmlFile      = Path.ChangeExtension(Path.Combine(htmlDir, name), "html");
                var featuredImage = string.Empty;
                _log.Info($"Processing '{htmlFile}'");
                foreach (var l in doc.Descendants().OfType <LinkInline>().Where(l => l.IsImage))
                {
                    var img = new FileInfo(Path.Combine(mdFile.DirectoryName, l.Url));
                    if (img.Exists)
                    {
                        if (_config.InputDirectory != _config.OutputDirectory)
                        {
                            img.CopyTo(Path.Combine(htmlDir, l.Url), true);
                        }
                        l.Url = _config.ImagePrefix + name + '/' + l.Url;
                        if (string.IsNullOrEmpty(featuredImage))
                        {
                            featuredImage = l.Url;
                        }
                    }
                }
                using (var writer = new StreamWriter(new FileStream(htmlFile, FileMode.Create)))
                {
                    var renderer = new HtmlRenderer(writer);
                    pipeline.Setup(renderer);
                    renderer.Render(doc);
                    writer.Flush();
                }
                var yaml = doc.Descendants().OfType <YamlFrontMatterBlock>().FirstOrDefault();
                _index.Add(name, featuredImage, yaml?.Lines.Lines.Select(l => l.ToString()));
            }
        }
        public static void TestSpec(string baseUrl, string markdown, string expectedLink)
        {
            var pipeline = new MarkdownPipelineBuilder().Build();

            var writer   = new StringWriter();
            var renderer = new HtmlRenderer(writer);

            if (baseUrl != null)
            {
                renderer.BaseUrl = new Uri(baseUrl);
            }
            pipeline.Setup(renderer);

            var document = MarkdownParser.Parse(markdown, pipeline);

            renderer.Render(document);
            writer.Flush();

            Assert.That(writer.ToString(), Contains.Substring("=\"" + expectedLink + "\""));
        }
Exemple #18
0
        public void RendersParsedHtml()
        {
            string _markdown = $"[file://{Directory.GetCurrentDirectory()}/gist.js]";
            var    _pipeline = new MarkdownPipelineBuilder()
                               .UseEmbeddedGists(config =>
            {
                config.AddBaseUrl("file://");
            }).Build();

            _pipeline.Setup(_renderer);

            var _html   = Markdown.ToHtml(_markdown, _pipeline);
            var _result = new HtmlDocument();

            _result.LoadHtml($"<!DOCTYPE html><html><body>{_html}</body></html>");

            _html.Trim().Should().NotContain("document.write");
            _result.DocumentNode.SelectNodes("//p/link").Count().Should().Be(1);
            _result.DocumentNode.SelectSingleNode("//p/link").Attributes["test-attribute"].Value.Should().Be("confirmed");
            _result.GetElementbyId("file-test-gist-LC1").InnerText.Should().Be("This is a test gist");
        }
Exemple #19
0
        public string Render(string markdown, Func <string, string> linkRewriter = null)
        {
            var writer   = new StringWriter();
            var renderer = new HtmlRenderer(writer);

            renderer.LinkRewriter = linkRewriter;

            var pipeline = new MarkdownPipelineBuilder()
                           .UseAdvancedExtensions()
                           .UseHighlightJs(new CustomHighlightJsEngine())
                           .Build();

            pipeline.Setup(renderer);

            var document = Markdown.Parse(markdown, pipeline);

            renderer.Render(document);
            writer.Flush();

            return(writer.ToString());
        }
        public static string Converter2(string mixedHtmlAndMarkdown, Action <MarkdownDocument> transform, MarkdownPipeline pipeline)
        {
            var    converter    = new Html2Markdown.Converter();
            string markdownOnly = converter.Convert(mixedHtmlAndMarkdown);

            pipeline = new MarkdownPipelineBuilder()
                       .UseAdvancedExtensions()
                       .UsePipeTables()
                       .Build();
            pipeline.Extensions.AddIfNotAlready <SoftlineBreakAsHardlineExtension>();
            MarkdownDocument ast = Markdown.Parse(markdownOnly, pipeline);

            transform(ast);
            using (var writer = new StringWriter())
            {
                var renderer = new HtmlRenderer(writer);
                pipeline.Setup(renderer);
                renderer.Render(ast);
                writer.Flush();
                return(writer.ToString());
            }
        }
Exemple #21
0
        public override void Transform(ExtensionHtmlRenderer extensionHtmlRenderer, WorkflowNotesBlock block, Diagram diagram)
        {
            var(element, elementsEnumerable) = _provider.GetBpmnElements(new EaProvider.Path(diagram.Name));
            var elements = elementsEnumerable.ToList();

            elements.Sort(new BpmnElement.AliasComparer());
            var sb = new StringBuilder();

            sb.AppendLine($@"# {element.Name}");
            var converter = new Html2Markdown.Converter();

            foreach (BpmnElement e in elements)
            {
                string           name    = string.IsNullOrEmpty(e.Name) ? e.Alias : e.Name;
                string           notes   = converter.Convert(e.Notes);
                MarkdownDocument notesMd = Markdown.Parse(notes);
                notesMd.IncreaseHeadingLevel(2);
                string normalizedNotes = null;
                using (var writer = new StringWriter())
                {
                    var pipeline = new MarkdownPipelineBuilder().Build();
                    pipeline.Extensions.AddIfNotAlready <SoftlineBreakAsHardlineExtension>();
                    var renderer = new NormalizeRenderer(writer);
                    pipeline.Setup(renderer);
                    renderer.Render(notesMd);
                    writer.Flush();
                    normalizedNotes = writer.ToString();
                }

                sb.AppendLine($@"## {name}");
                sb.AppendLine($@"Lane: {e.Lane}");
                sb.AppendLine();
                sb.AppendLine($@"Description:");
                sb.AppendLine(normalizedNotes);
            }
            MarkdownDocument document = Markdown.Parse(sb.ToString());

            Replace(block, document);
        }
Exemple #22
0
        public async Task <string> GetHtml(string localGetImgRelativeURI)
        {
            var    httpClient = new HttpClient();
            string mdBody     = await httpClient.GetStringAsync(_rawSourceMDUrl).ConfigureAwait(false);

            var pipeline = new MarkdownPipelineBuilder().UseAdvancedExtensions().Build();
            var document = MarkdownParser.Parse(mdBody, pipeline);

            var htmlRenderer = new HtmlRenderer(new StringWriter());

            // Old approach for building local images url.
            // Removed because it does not manage explicit <img> tag inside MD files
            //
            //htmlRenderer.BaseUrl = new Uri(_rawBaseSourceUrl);
            //if (localGetImgRelativeURI != null)
            //{
            //    htmlRenderer.LinkRewriter = (oldlink) =>
            //    {
            //        if (oldlink.StartsWith(_rawBaseSourceUrl))
            //        {
            //            return localGetImgRelativeURI + Convert.ToBase64String(Encoding.UTF8.GetBytes(oldlink.Replace(_rawBaseSourceUrl, "")));
            //        }
            //        else
            //        {
            //            return oldlink;
            //        }
            //    };
            //}

            pipeline.Setup(htmlRenderer);
            htmlRenderer.Render(document);
            htmlRenderer.Writer.Flush();
            string htmlBody = htmlRenderer.Writer.ToString();

            htmlBody = await SetImgUrls(htmlBody, localGetImgRelativeURI);

            return(htmlBody);
        }
Exemple #23
0
    public string Transform(string source)
    {
        // https://github.com/xoofx/markdig/blob/master/src/Markdig.Tests/Specs/YamlSpecs.md
        // https://github.com/xoofx/markdig/blob/master/src/Markdig.Tests/Specs/BootstrapSpecs.md
        // https://github.com/xoofx/markdig/blob/master/src/Markdig.Tests/Specs/EmphasisExtraSpecs.md
        // https://github.com/xoofx/markdig/blob/master/src/Markdig.Tests/Specs/DefinitionListSpecs.md
        // https://github.com/xoofx/markdig/blob/master/src/Markdig.Tests/Specs/FootnotesSpecs.md
        // https://github.com/xoofx/markdig/blob/master/src/Markdig.Tests/Specs/AutoLinks.md
        // https://github.com/xoofx/markdig/blob/master/src/Markdig.Tests/Specs/ListExtraSpecs.md
        // https://github.com/xoofx/markdig/blob/master/src/Markdig.Tests/Specs/MediaSpecs.md
        // https://github.com/xoofx/markdig/blob/master/src/Markdig.Tests/Specs/AbbreviationSpecs.md
        // https://github.com/xoofx/markdig/blob/master/src/Markdig.Tests/Specs/HardlineBreakSpecs.md
        // https://github.com/xoofx/markdig/blob/master/src/Markdig.Tests/Specs/FigureFooterAndCiteSpecs.md
        // https://github.com/ilich/Markdig.Prism/blob/main/src/Markdig.Prism/PrismCodeBlockRenderer.cs

        var pipeline = new MarkdownPipelineBuilder()
                       .UseYamlFrontMatter()
                       // https://github.com/xoofx/markdig/blob/master/src/Markdig.Tests/Specs/EmojiSpecs.md
                       //.UseEmojiAndSmiley(new Markdig.Extensions.Emoji.EmojiMapping(new Dictionary<string, string>() { { ":smiley:", "♥" } }, new Dictionary<string, string>()))

                       // UseAdvancedExtensions 2021-01-25
                       // .UseAbbreviations()
                       // https://github.com/xoofx/markdig/blob/master/src/Markdig.Tests/Specs/AutoIdentifierSpecs.md
                       .UseAutoIdentifiers()
                       // .UseCitations()
                       // .UseCustomContainers()
                       // .UseDefinitionLists()
                       // .UseEmphasisExtras()
                       // .UseFigures()
                       // .UseFooters()
                       // .UseFootnotes()
                       //.UseGridTables()
                       // .UseMathematics()
                       // .UseMediaLinks()
                       // https://github.com/xoofx/markdig/blob/master/src/Markdig.Tests/Specs/PipeTableSpecs.md
                       .UsePipeTables()
                       // .UseListExtras()
                       // .UseTaskLists()
                       // .UseDiagrams()
                       // .UseAutoLinks()
                       // https://github.com/xoofx/markdig/blob/master/src/Markdig.Tests/Specs/GenericAttributesSpecs.md
                       .UseGenericAttributes()
                       .Build();

        var doc = Markdown.Parse(source, pipeline);

        // Process headings to insert an intermediate LinkInline
        foreach (var headingBlock in doc.Descendants <HeadingBlock>())
        {
            var inline         = new LinkInline($"#{headingBlock.GetAttributes().Id}", null);
            var previousInline = headingBlock.Inline;
            headingBlock.Inline = null;
            inline.AppendChild(previousInline);
            headingBlock.Inline = inline;
        }

        var anchorTags = doc.Descendants <LinkInline>();

        foreach (var anchor in anchorTags)
        {
            if (anchor is LinkInline link && !link.IsImage)
            {
                if (!anchor.Url.StartsWith(GlobalFunctions.Instance.Url))
                {
                    link.GetAttributes().AddClass("external");
                }
            }

            // TODO disable pending Medium response...
            // if (anchor is LinkInline imageLink && imageLink.IsImage)
            // {
            //     if (imageLink.Url.StartsWith("/assets"))
            //     {
            //         imageLink.Url = GlobalFunctions.Instance.Url + imageLink.Url;
            //     }
            // }
        }

        // Render the doc
        var writer   = new StringWriter();
        var renderer = new HtmlRenderer(writer);

        pipeline.Setup(renderer);
        renderer.Render(doc);

        return(writer.ToString().Trim());
    }
        private string ConvertMarkdownToHTML(List <MarkdownFile> files)
        {
            Log("Converting Markdown to HTML");
            StringBuilder sb = new StringBuilder();

            for (var i = 0; i < files.Count; i++)
            {
                var mf   = files[i];
                var file = new FileInfo(files[i].AbsolutePath);

                Log($"parsing file {file.Name}", LogLevel.Debug);
                var htmlfile = file.FullName.Replace(".md", ".html");
                var md       = File.ReadAllText(file.FullName);

                //setup the markdown pipeline to support tables
                var pipeline = new MarkdownPipelineBuilder().UsePipeTables().Build();

                //parse the markdown document so we can alter it later
                var document = (MarkdownObject)Markdown.Parse(md, pipeline);

                //adjust the links
                CorrectLinksAndImages(document, file, mf);

                string html    = null;
                var    builder = new StringBuilder();
                using (var writer = new System.IO.StringWriter(builder))
                {
                    // write the HTML output
                    var renderer = new HtmlRenderer(writer);
                    pipeline.Setup(renderer);
                    renderer.Render(document);
                }
                html = builder.ToString();

                //add html anchor
                var anchorPath = file.FullName.Substring(_path.Length);
                anchorPath = anchorPath.Replace("\\", "");
                anchorPath = anchorPath.ToLower();
                anchorPath = anchorPath.Replace(".md", "");

                var relativePath = file.FullName.Substring(_path.Length);

                var anchor = $"<a id=\"{anchorPath}\">&nbsp;</a>";

                Log($"\tAnchor: {anchorPath}");

                html = anchor + html;

                if (_options.PathToHeading)
                {
                    var filename = file.Name;
                    filename = HttpUtility.UrlDecode(relativePath);
                    var heading = $"<b>{filename}</b>";
                    html = heading + html;
                }

                if (_options.Heading)
                {
                    var filename = file.Name.Replace(".md", "");
                    filename = HttpUtility.UrlDecode(filename);
                    var heading = $"<h1>{filename}</h1>";
                    html = heading + html;
                }



                if (_options.BreakPage)
                {
                    //if not one the last page
                    if (i + 1 < files.Count)
                    {
                        Log("Adding new page to PDF");
                        html = "<div style='page-break-after: always;'>" + html + "</div>";
                    }
                }

                if (_options.Debug)
                {
                    Log($"html:\n{html}");
                }
                sb.Append(html);
            }

            var result = sb.ToString();


            return(result);
        }
Exemple #25
0
        /// <summary>
        /// Constructs a DocComment instance from the documentation comments
        /// associated with a source code element.
        /// </summary>
        /// <param name="docComments">The doc comments from the source code</param>
        /// <param name="name">The name of the element</param>
        /// <param name="deprecated">Flag indicating whether or not the element had a Deprecated attribute</param>
        /// <param name="replacement">The name of the replacement element for deprecated elements, if given</param>
        public DocComment(IEnumerable <string> docComments, string name, bool deprecated, string replacement)
        {
            string GetHeadingText(HeadingBlock heading)
            {
                var sb = new StringBuilder();

                foreach (var item in heading.Inline)
                {
                    sb.Append(item.ToString());
                }
                return(sb.ToString());
            }

            string GetParagraphText(LeafBlock leaf)
            {
                var sb = new StringBuilder();

                foreach (var item in leaf.Inline)
                {
                    sb.Append(item.ToString());
                }
                return(sb.ToString());
            }

            string ToMarkdown(IEnumerable <Block> blocks)
            {
                var writer   = new StringWriter();
                var renderer = new NormalizeRenderer(writer);
                var pipeline = new MarkdownPipelineBuilder().Build();

                pipeline.Setup(renderer);
                foreach (var block in blocks)
                {
                    renderer.Render(block);
                }
                // We convert \n to \r because the YAML serialization will eventually
                // output \n\n for \n, but \r\n for \r.
                return(writer.ToString().TrimEnd().Replace('\n', '\r'));
            }

            List <ValueTuple <string, List <Block> > > BreakIntoSections(IEnumerable <Block> blocks, int level)
            {
                var key    = "";
                var accum  = new List <Block>();
                var result = new List <ValueTuple <string, List <Block> > >();

                foreach (var block in blocks)
                {
                    if (block is HeadingBlock heading)
                    {
                        if (heading.Level == level)
                        {
                            if (accum.Count > 0)
                            {
                                result.Add(new ValueTuple <string, List <Block> >(key, accum));
                                accum = new List <Block>();
                            }
                            key = GetHeadingText(heading);
                        }
                        else
                        {
                            accum.Add(block);
                        }
                    }
                    else
                    {
                        accum.Add(block);
                    }
                }

                if (accum.Count > 0)
                {
                    result.Add(new ValueTuple <string, List <Block> >(key, accum));
                }

                return(result);
            }

            void ParseListSection(IEnumerable <Block> blocks, List <string> accum, bool lowerCase)
            {
                foreach (var block in blocks)
                {
                    if (block is ListBlock list)
                    {
                        foreach (var sub in block.Descendants())
                        {
                            if (sub is ListItemBlock item)
                            {
                                // Some special treatment for funky doc comments in some of the Canon
                                if (item.Count == 1 && item.LastChild is LeafBlock leaf && leaf.Inline != null &&
                                    leaf.Inline.FirstChild is LiteralInline literal)
                                {
                                    var itemText = lowerCase ? GetParagraphText(leaf).ToLowerInvariant() : GetParagraphText(leaf);
                                    if (itemText.StartsWith("@\"") && itemText.EndsWith("\""))
                                    {
                                        itemText = itemText.Substring(2, itemText.Length - 3);
                                    }
                                    literal.Content = new Markdig.Helpers.StringSlice(itemText.ToLowerInvariant());
                                }
                                accum.Add(ToMarkdown(new Block[] { item }));
                            }
                        }
                    }
                }
            }

            void ParseMapSection(IEnumerable <Block> blocks, Dictionary <string, string> accum)
            {
                var subsections = BreakIntoSections(blocks, 2);

                foreach ((var key, var subs) in subsections)
                {
                    // TODO: when we add the ability to flag warnings from the doc comment builder,
                    // we should check here for duplicate keys and generate a warning if appropriate.
                    accum[key] = ToMarkdown(subs);
                }
            }

            // First element is not matching, second is matching
            (List <Block>, List <Block>) PartitionNestedSection(IEnumerable <Block> blocks, int level, string name)
            {
                var inMatch = false;
                var result  = (new List <Block>(), new List <Block>());

                foreach (var block in blocks)
                {
                    var skip = false;
                    if ((block is HeadingBlock heading) && (heading.Level == level))
                    {
                        inMatch = GetHeadingText(heading).Equals(name);
                        skip    = true;
                    }
                    if (inMatch)
                    {
                        if (!skip)
                        {
                            result.Item2.Add(block);
                        }
                    }
                    else
                    {
                        result.Item1.Add(block);
                    }
                }

                return(result);
            }

            // Initialize to safe empty values
            this.Summary        = "";
            this.Description    = "";
            this.ShortSummary   = "";
            this.Documentation  = "";
            this.Input          = new Dictionary <string, string>();
            this.Output         = "";
            this.TypeParameters = new Dictionary <string, string>();
            this.Example        = "";
            this.Remarks        = "";
            this.SeeAlso        = new List <string>();
            this.References     = "";

            var deprecationSummary = String.IsNullOrWhiteSpace(replacement)
                                    ? DiagnosticItem.Message(WarningCode.DeprecationWithoutRedirect, new string[] { name })
                                    : DiagnosticItem.Message(WarningCode.DeprecationWithRedirect, new string[] { name, "@\"" + replacement + "\"" });
            var deprecationDetails = "";

            var text = String.Join("\n", docComments);

            // Only parse if there are comments to parse
            if (!string.IsNullOrWhiteSpace(text))
            {
                var          doc                = Markdown.Parse(text);
                var          sections           = BreakIntoSections(doc, 1);
                List <Block> summarySection     = new List <Block>();
                List <Block> descriptionSection = new List <Block>();

                foreach ((var tag, var section) in sections)
                {
                    switch (tag)
                    {
                    case "Summary":
                        this.Summary = ToMarkdown(section);
                        summarySection.AddRange(section);
                        // For now, the short hover information gets the first paragraph of the summary.
                        this.ShortSummary = ToMarkdown(section.GetRange(0, 1));
                        break;

                    case "Deprecated":
                        if (String.IsNullOrWhiteSpace(name))
                        {
                            deprecationSummary = ToMarkdown(section.GetRange(0, 1));
                            if (section.Count > 1)
                            {
                                deprecationDetails = ToMarkdown(section.GetRange(1, section.Count - 1));
                            }
                        }
                        else
                        {
                            deprecationDetails = ToMarkdown(section);
                        }
                        deprecated = true;
                        break;

                    case "Description":
                        this.Description   = ToMarkdown(section);
                        descriptionSection = section;
                        break;

                    case "Input":
                        ParseMapSection(section, this.Input);
                        break;

                    case "Output":
                        this.Output = ToMarkdown(section);
                        break;

                    case "Type Parameters":
                        ParseMapSection(section, this.TypeParameters);
                        break;

                    case "Example":
                        this.Example = ToMarkdown(section);
                        break;

                    case "Remarks":
                        (var remarks, var examples) = PartitionNestedSection(section, 2, "Example");
                        if ((examples.Count > 0) && (this.Example == ""))
                        {
                            this.Example = ToMarkdown(examples);
                        }
                        this.Remarks = ToMarkdown(remarks);
                        break;

                    case "See Also":
                        // seeAlso is a list of UIDs, which are all lower case,
                        // so pass true to lowercase all strings found in this section
                        ParseListSection(section, this.SeeAlso, true);
                        break;

                    case "References":
                        this.References = ToMarkdown(section);
                        break;

                    default:
                        // TODO: add diagnostic warning about unknown tag
                        break;
                    }
                }


                this.Documentation = ToMarkdown(summarySection.Concat(descriptionSection));
            }

            if (deprecated)
            {
                var shortDeprecationText = DeprecatedWarning + "\r" + deprecationSummary;
                var longDeprecationText  = shortDeprecationText + (String.IsNullOrWhiteSpace(deprecationDetails) ? "" : "\r") + deprecationDetails;
                this.Summary      += "\r" + longDeprecationText;
                this.ShortSummary  = shortDeprecationText;
                this.Documentation = deprecationSummary;
            }
        }
Exemple #26
0
        private string ConvertMarkdownToHTML(List <MarkdownFile> files)
        {
            Log("Converting Markdown to HTML");
            StringBuilder sb = new StringBuilder();



            for (var i = 0; i < files.Count; i++)
            {
                var mf   = files[i];
                var file = new FileInfo(files[i].AbsolutePath);

                Log($"parsing file {file.Name}", LogLevel.Debug);
                var htmlfile = file.FullName.Replace(".md", ".html");

                if (!File.Exists(file.FullName))
                {
                    Log($"File {file.FullName} specified in the order file was not found and will be skipped!", LogLevel.Error);
                    continue;
                }

                var md = File.ReadAllText(file.FullName);

                // remove scalings from image links
                var regexImageScalings = @"\(((.[^\)]*?(png|jpg|jpeg))( =((\d+).*x(\d+).*)))\)";
                md = Regex.Replace(md, regexImageScalings, @"($2){width=$6 height=$7}");

                //setup the markdown pipeline to support tables
                var pipeline = new MarkdownPipelineBuilder()
                               .UsePipeTables()
                               .UseEmojiAndSmiley()
                               .UseAdvancedExtensions()
                               .Build();

                //parse the markdown document so we can alter it later
                var document = (MarkdownObject)Markdown.Parse(md, pipeline);

                //adjust the links
                CorrectLinksAndImages(document, file, mf);

                string html    = null;
                var    builder = new StringBuilder();
                using (var writer = new System.IO.StringWriter(builder))
                {
                    // write the HTML output
                    var renderer = new HtmlRenderer(writer);
                    pipeline.Setup(renderer);
                    renderer.Render(document);
                }
                html = builder.ToString();

                //add html anchor
                var anchorPath = file.FullName.Substring(_path.Length);
                anchorPath = anchorPath.Replace("\\", "");
                anchorPath = anchorPath.ToLower();
                anchorPath = anchorPath.Replace(".md", "");

                var relativePath = file.FullName.Substring(_path.Length);

                var anchor = $"<a id=\"{anchorPath}\">&nbsp;</a>";

                Log($"\tAnchor: {anchorPath}");

                html = anchor + html;

                if (_options.PathToHeading)
                {
                    var filename = file.Name;
                    filename = HttpUtility.UrlDecode(relativePath);
                    var heading = $"<b>{filename}</b>";
                    html = heading + html;
                }

                if (_options.Heading)
                {
                    var filename = file.Name.Replace(".md", "");
                    filename = HttpUtility.UrlDecode(filename);
                    var filenameEscapes = new Dictionary <string, string>
                    {
                        { "%3A", ":" },
                        { "%3C", "<" },
                        { "%3E", ">" },
                        { "%2A", "*" },
                        { "%3F", "?" },
                        { "%7C", "|" },
                        { "%2D", "-" },
                        { "%22", "\"" },
                        { "-", " " }
                    };

                    var title = new StringBuilder(filename);
                    foreach (var filenameEscape in filenameEscapes)
                    {
                        title.Replace(filenameEscape.Key, filenameEscape.Value);
                    }

                    var heading = $"<h1>{title.ToString()}</h1>";
                    html = heading + html;
                }

                if (_options.BreakPage)
                {
                    //if not one the last page
                    if (i + 1 < files.Count)
                    {
                        Log("Adding new page to PDF");
                        html = "<div style='page-break-after: always;'>" + html + "</div>";
                    }
                }

                if (_options.Debug)
                {
                    Log($"html:\n{html}");
                }
                sb.Append(html);
            }

            var result = sb.ToString();


            return(result);
        }