protected override void Write(VT100Renderer renderer, FencedCodeBlock obj) { if (obj?.Lines.Lines != null) { foreach (StringLine codeLine in obj.Lines.Lines) { if (!string.IsNullOrWhiteSpace(codeLine.ToString())) { // If the code block is of type YAML, then tab to right to improve readability. // This specifically helps for parameters help content. if (string.Equals(obj.Info, "yaml", StringComparison.OrdinalIgnoreCase)) { renderer.Write("\t").WriteLine(codeLine.ToString()); } else { renderer.WriteLine(renderer.EscapeSequences.FormatCode(codeLine.ToString(), isInline: false)); } } } // Add a blank line after the code block for better readability. renderer.WriteLine(); } }
private void RenderWithIndent(VT100Renderer renderer, MarkdownObject block, char listBullet, int indentLevel) { // Indent left by 2 for each level on list. string indent = Padding(indentLevel * 2); if (block is ParagraphBlock paragraphBlock) { renderer.Write(indent).Write(listBullet).Write(" ").Write(paragraphBlock.Inline); } else { // If there is a sublist, the block is a ListBlock instead of ParagraphBlock. if (block is ListBlock subList) { foreach (var subListItem in subList) { if (subListItem is ListItemBlock subListItemBlock) { foreach (var line in subListItemBlock) { // Increment indent level for sub list. RenderWithIndent(renderer, line, listBullet, indentLevel + 1); } } } } } }
/// <summary> /// Convert from Markdown string to VT100 encoded string or HTML. Returns MarkdownInfo object. /// </summary> /// <param name="markdownString">String with Markdown content to be converted.</param> /// <param name="conversionType">Specifies type of conversion, either VT100 or HTML.</param> /// <param name="optionInfo">Specifies the rendering options for VT100 rendering.</param> /// <returns>MarkdownInfo object with the converted output.</returns> public static MarkdownInfo Convert(string markdownString, MarkdownConversionType conversionType, MarkdownOptionInfo optionInfo) { var renderInfo = new MarkdownInfo(); var writer = new StringWriter(); MarkdownPipeline pipeline = null; if (conversionType.HasFlag(MarkdownConversionType.HTML)) { pipeline = new MarkdownPipelineBuilder().UseAdvancedExtensions().Build(); var renderer = new Markdig.Renderers.HtmlRenderer(writer); renderInfo.Html = Markdig.Markdown.Convert(markdownString, renderer, pipeline).ToString(); } if (conversionType.HasFlag(MarkdownConversionType.VT100)) { pipeline = new MarkdownPipelineBuilder().Build(); // Use the VT100 renderer. var renderer = new VT100Renderer(writer, optionInfo); renderInfo.VT100EncodedString = Markdig.Markdown.Convert(markdownString, renderer, pipeline).ToString(); } // Always have AST available. var parsed = Markdig.Markdown.Parse(markdownString, pipeline); renderInfo.Tokens = parsed; return(renderInfo); }
protected override void Write(VT100Renderer renderer, ParagraphBlock obj) { // Call the renderer for children, leaf inline or line breaks. renderer.WriteChildren(obj.Inline); // Add new line at the end of the paragraph. renderer.WriteLine(); }
private static void RenderNumberedList(VT100Renderer renderer, ListItemBlock block, int index) { // For a numbered list, we need to make sure the index is incremented. foreach (var line in block) { if (line is ParagraphBlock paragraphBlock) { renderer.Write(index.ToString()).Write(". ").Write(paragraphBlock.Inline); } } }
protected override void Write(VT100Renderer renderer, QuoteBlock obj) { // Iterate through each item and add the quote character before the content. foreach (var item in obj) { renderer.Write(obj.QuoteChar).Write(" ").Write(item); } // Add blank line after the quote block. renderer.WriteLine(); }
protected override void Write(VT100Renderer renderer, LinkInline obj) { // Format link as image or link. if (obj.IsImage) { renderer.Write(renderer.EscapeSequences.FormatImage(obj.FirstChild.ToString())); } else { renderer.Write(renderer.EscapeSequences.FormatLink(obj.FirstChild.ToString(), obj.Url)); } }
protected override void Write(VT100Renderer renderer, ListItemBlock obj) { if (obj.Parent is ListBlock parent) { if (!parent.IsOrdered) { foreach (var line in obj) { RenderWithIndent(renderer, line, parent.BulletType, 0); } } } }
protected override void Write(VT100Renderer renderer, LineBreakInline obj) { // If it is a hard line break add new line at the end. // Else, add a space for after the last character to improve readability. if (obj.IsHard) { renderer.WriteLine(); } else { renderer.Write(" "); } }
protected override void Write(VT100Renderer renderer, LeafInline obj) { // If the next sibling is null, then this is the last line in the paragraph. // Add new line character at the end. // Else just write without newline at the end. if (obj.NextSibling == null) { renderer.WriteLine(obj.ToString()); } else { renderer.Write(obj.ToString()); } }
protected override void Write(VT100Renderer renderer, HeadingBlock obj) { string headerText = obj?.Inline?.FirstChild?.ToString(); if (!string.IsNullOrEmpty(headerText)) { // Format header and then add blank line to improve readability. switch (obj.Level) { case 1: renderer.WriteLine(renderer.EscapeSequences.FormatHeader1(headerText)); renderer.WriteLine(); break; case 2: renderer.WriteLine(renderer.EscapeSequences.FormatHeader2(headerText)); renderer.WriteLine(); break; case 3: renderer.WriteLine(renderer.EscapeSequences.FormatHeader3(headerText)); renderer.WriteLine(); break; case 4: renderer.WriteLine(renderer.EscapeSequences.FormatHeader4(headerText)); renderer.WriteLine(); break; case 5: renderer.WriteLine(renderer.EscapeSequences.FormatHeader5(headerText)); renderer.WriteLine(); break; case 6: renderer.WriteLine(renderer.EscapeSequences.FormatHeader6(headerText)); renderer.WriteLine(); break; } } }
protected override void Write(VT100Renderer renderer, ListBlock obj) { // start index of a numbered block. int index = 1; foreach (var item in obj) { if (item is ListItemBlock listItem) { if (obj.IsOrdered) { RenderNumberedList(renderer, listItem, index++); } else { renderer.Write(listItem); } } } renderer.WriteLine(); }
protected override void Write(VT100Renderer renderer, HeadingBlock obj) { // Format header and then add blank line to improve readability. switch (obj.Level) { case 1: renderer.WriteLine(renderer.EscapeSequences.FormatHeader1(obj.Inline.FirstChild.ToString())); renderer.WriteLine(); break; case 2: renderer.WriteLine(renderer.EscapeSequences.FormatHeader2(obj.Inline.FirstChild.ToString())); renderer.WriteLine(); break; case 3: renderer.WriteLine(renderer.EscapeSequences.FormatHeader3(obj.Inline.FirstChild.ToString())); renderer.WriteLine(); break; case 4: renderer.WriteLine(renderer.EscapeSequences.FormatHeader4(obj.Inline.FirstChild.ToString())); renderer.WriteLine(); break; case 5: renderer.WriteLine(renderer.EscapeSequences.FormatHeader5(obj.Inline.FirstChild.ToString())); renderer.WriteLine(); break; case 6: renderer.WriteLine(renderer.EscapeSequences.FormatHeader6(obj.Inline.FirstChild.ToString())); renderer.WriteLine(); break; } }
protected override void Write(VT100Renderer renderer, EmphasisInline obj) { renderer.Write(renderer.EscapeSequences.FormatEmphasis(obj.FirstChild.ToString(), isBold: obj.DelimiterCount == 2 ? true : false)); }
protected override void Write(VT100Renderer renderer, CodeInline obj) { renderer.Write(renderer.EscapeSequences.FormatCode(obj.Content, isInline: true)); }