Skip to content

Add Markdown component using Markdig and HTML pipeline#42

Merged
LittleLittleCloud merged 14 commits intomainfrom
copilot/add-markdown-component
Oct 24, 2025
Merged

Add Markdown component using Markdig and HTML pipeline#42
LittleLittleCloud merged 14 commits intomainfrom
copilot/add-markdown-component

Conversation

Copy link
Contributor

Copilot AI commented Oct 22, 2025

Overview

This PR adds a new Markdown component to RazorConsole that parses and renders markdown content using Markdig by converting markdown to HTML and leveraging the existing HTML rendering pipeline.

What's New

Markdown Component

The new <Markdown> component allows you to render markdown content directly in your console applications:

<Markdown Content="@markdownContent" />

Supported Features

  • Headings (H1-H6) - Rendered with color-coded styling (h1=yellow, h2=cyan, h3=green, h4=blue, h5=magenta, h6=grey)
  • Paragraphs - With inline formatting support (bold, italic, inline code)
  • Code Blocks - Rendered with syntax highlighting via SyntaxHighlightingService
  • Lists - Both ordered (numbered) and unordered (bulleted) lists
  • Block Quotes - Rendered with indentation and styling
  • Thematic Breaks (horizontal rules) - Rendered as grey separator lines
  • Inline formatting - Bold, italic, inline code, and links

Example

@using RazorConsole.Components

<Panel Title="Documentation" Expand="true">
    <Markdown Content="@docs" />
</Panel>

@code {
    private string docs = @"
# Getting Started

Welcome to **RazorConsole**! This is *italic* text.

## Features

- Easy to use
- Built on Spectre.Console
- Supports markdown

### Code Example

```csharp
Console.WriteLine(""Hello, World!"");

This is a quote block!
";
}


## Implementation Details

### Architecture

- **MarkdownRenderingService** - Converts markdown to HTML using Markdig's advanced extensions pipeline
- **HTML Pipeline Integration** - Uses the existing `HtmlVdomConverter` to parse HTML into VDOM nodes
- **HTML Element Translators** - Implements translators for all markdown HTML elements
- **Simplified Design** - No custom element types or JSON serialization needed

The component converts markdown to HTML, wraps it in a root `<div>` element for XML parsing, and injects it using `MarkupString`. The HTML rendering pipeline with dedicated translators handles the rendering.

### New HTML Translators

Added 5 new translators to support all markdown elements:

- **HtmlHeadingElementTranslator** - Handles h1-h6 with color-coded, bold styling
- **HtmlParagraphElementTranslator** - Handles paragraph tags properly inline
- **HtmlCodeBlockElementTranslator** - Handles pre/code blocks with syntax highlighting integration
- **HtmlBlockquoteElementTranslator** - Renders blockquotes as indented panels with grey borders
- **HtmlHrElementTranslator** - Renders horizontal rules as grey separator lines

### Dependencies

Added `Markdig` v0.39.0 package for markdown parsing.

## Testing

Added comprehensive unit tests covering:
- HTML conversion from markdown (headings, paragraphs)
- Bold and italic inline formatting
- Code block conversion
- Ordered and unordered list conversion
- Component rendering with dependency injection

All 69 tests pass on both .NET 8.0 and .NET 9.0.

## Gallery

The component is showcased in the component gallery with a comprehensive example demonstrating all supported markdown features. Navigate to the "Markdown" tab to see it in action.

## Rendering Status

All markdown elements are now fully supported:

- ✅ **Headings** (h1-h6) - Fully rendered with color-coded styling
- ✅ **Paragraphs** (p) - Fully rendered with inline content
- ✅ **Code Blocks** (pre/code) - Fully rendered with syntax highlighting
- ✅ **Lists** (ul/ol/li) - Fully rendered via `HtmlListElementTranslator`
- ✅ **Blockquotes** - Fully rendered with indentation and styling
- ✅ **Horizontal Rules** (hr) - Fully rendered as separator lines
- ✅ **Inline formatting** - Bold, italic, inline code working via `HtmlInlineTextElementTranslator`

Fixes LittleLittleCloud/RazorConsole#21

<!-- START COPILOT CODING AGENT SUFFIX -->



<details>

<summary>Original prompt</summary>

> 
> ----
> 
> *This section details on the original issue you should resolve*
> 
> <issue_title>Add markdown component</issue_title>
> <issue_description>-Use markdig to parse markdown
> - for code block, use SyntaxHighlighter
> </issue_description>
> 
> ## Comments on the Issue (you are @copilot in this section)
> 
> <comments>
> </comments>
> 


</details>

Fixes LittleLittleCloud/RazorConsole#21

<!-- START COPILOT CODING AGENT TIPS -->
---

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs.

Copilot AI and others added 2 commits October 22, 2025 01:01
Co-authored-by: LittleLittleCloud <16876986+LittleLittleCloud@users.noreply.github.com>
Co-authored-by: LittleLittleCloud <16876986+LittleLittleCloud@users.noreply.github.com>
Copilot AI changed the title [WIP] Add markdown component with markdig and SyntaxHighlighter Add Markdown component with Markdig parser and syntax highlighting Oct 22, 2025
@LittleLittleCloud
Copy link
Member

@copilot
use a different approach

  • markdown to html using markdig
  • then use existing pipeline to render html into IRenderable

Co-authored-by: LittleLittleCloud <16876986+LittleLittleCloud@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Oct 22, 2025

@copilot
use a different approach

  • markdown to html using markdig...

Refactored to use the markdown-to-HTML approach with the existing pipeline (commit a0d0598).

The implementation now:

  • Converts markdown to HTML using Markdig
  • Uses MarkupString to inject the HTML
  • Leverages the existing HtmlVdomConverter and VDOM translators

Lists are already working via HtmlListElementTranslator. The remaining HTML elements (h1-h6, pre/code, blockquote, hr) currently show as "Untranslated VDOM" since translators don't exist for them yet. Should I add translators for these remaining elements, or is the current approach sufficient?

Markdown rendering with HTML pipeline - lists working, other elements need translators

Copilot AI changed the title Add Markdown component with Markdig parser and syntax highlighting Add Markdown component using Markdig and HTML pipeline Oct 22, 2025
@LittleLittleCloud
Copy link
Member

@copilot yes, implement the remaining html unsupported tag

…te, hr, p)

Co-authored-by: LittleLittleCloud <16876986+LittleLittleCloud@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Oct 22, 2025

@copilot yes, implement the remaining html unsupported tag

Implemented all remaining HTML translators (commit bf3150c):

Added translators:

  • HtmlHeadingElementTranslator - h1-h6 with color-coded styling
  • HtmlCodeBlockElementTranslator - pre/code with syntax highlighting via SyntaxHighlightingService
  • HtmlBlockquoteElementTranslator - blockquotes with indentation
  • HtmlHrElementTranslator - horizontal rules
  • HtmlParagraphElementTranslator - paragraph tags

All markdown elements now render properly:

╭─Markdown Demo - Complete──────────────────────────────────────╮
│ Markdown Component                                            │
│ This is a demo of the markdown component using HTML pipeline! │
│ Features                                                      │
│ • Parse markdown using Markdig                                │
│ • Convert to HTML                                             │
│ • Use existing HTML rendering pipeline                        │
│ Code Example                                                  │
│ 1 public class HelloWorld                                     │
│ 2 {                                                           │
│ 3     public static void Main()                               │
│ 4     {                                                       │
│ 5         Console.WriteLine("Hello from Markdown!");          │
│ 6     }                                                       │
│ 7 }                                                           │
│   This is a quote block showing markdown rendering works!     │
│ ────────────────────────────────────────────────────────────  │
│ That's all for this demo!                                     │
╰───────────────────────────────────────────────────────────────╯

Headings are colored (yellow for h1, cyan for h2, green for h3), code blocks have syntax highlighting, blockquotes are indented, and horizontal rules display as separators.

Copy link
Member

@LittleLittleCloud LittleLittleCloud left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot I think tag p already supported, can you confirm?

@LittleLittleCloud
Copy link
Member

@copilot I think the tag 'p' already supported?

Copy link
Contributor Author

Copilot AI commented Oct 22, 2025

@copilot I think tag p already supported, can you confirm?

You're correct that <p> was already supported by ParagraphElementTranslator (Priority 30). However, that translator only handles <p> tags with text-only children.

Markdown generates <p> tags with mixed content (text + <strong>, <em>, <code>, etc.), which the original translator cannot handle - it returns false when children aren't all text nodes.

HtmlParagraphElementTranslator (Priority 195) runs after the original fails and handles the more general case with mixed content, enabling proper rendering of markdown paragraphs. Without it, markdown paragraphs show as "Untranslated VDOM" boxes.

Both translators are needed: the original for simple text-only paragraphs (used by other components), and the new one as a fallback for HTML-generated paragraphs with inline formatting.

@LittleLittleCloud LittleLittleCloud marked this pull request as ready for review October 24, 2025 15:01
@LittleLittleCloud LittleLittleCloud enabled auto-merge (squash) October 24, 2025 15:04
@LittleLittleCloud LittleLittleCloud merged commit 3cefb17 into main Oct 24, 2025
4 checks passed
@LittleLittleCloud LittleLittleCloud deleted the copilot/add-markdown-component branch October 24, 2025 15:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants