Is there an Escape function so I can add user generated content to markdown and ensure it is escaped correctly #750

Open
opened 2026-01-29 14:44:46 +00:00 by claunia · 0 comments
Owner

Originally created by @schallm on GitHub (Sep 10, 2025).

I'm working on writing some markdown from a system that allows user input. I want to include their text, but want to make sure their text doesn't get treated as markdown. I had AI create me a function, but was wondering if Markdig should have a built-in function for this kind of thing. Here is the function I'm using currently.

/// <summary>
/// Escapes user-entered text to prevent it from being interpreted as markdown.
/// This ensures user content is displayed as literal text rather than formatted markdown.
/// </summary>
/// <param name="text">The user-entered text to escape</param>
/// <returns>The escaped text safe for use in Markdown documents</returns>
public static string EscapeMarkdown(string text) {
    if (string.IsNullOrEmpty(text)) {
        return text;
    }

    // Dictionary of markdown special characters and their escaped equivalents
    var markdownChars = new Dictionary<char, string> {
        { '\\', @"\\" },  // Backslash must be first to avoid double-escaping
        { '*', @"\*" },   // Asterisk (bold/italic)
        { '_', @"\_" },   // Underscore (bold/italic)
        { '`', @"\`" },   // Backtick (code)
        { '#', @"\#" },   // Hash (headers)
        { '+', @"\+" },   // Plus (lists)
        { '-', @"\-" },   // Minus (lists, strikethrough)
        { '=', @"\=" },   // Equals (headers)
        { '|', @"\|" },   // Pipe (tables)
        { '{', @"\{" },   // Curly braces (various extensions)
        { '}', @"\}" },
        { '[', @"\[" },   // Square brackets (links, references)
        { ']', @"\]" },
        { '(', @"\(" },   // Parentheses (links)
        { ')', @"\)" },
        { '<', @"\<" },   // Angle brackets (HTML, autolinks)
        { '>', @"\>" },   // Greater than (blockquotes)
        { '!', @"\!" },   // Exclamation (images)
        { '~', @"\~" },   // Tilde (strikethrough)
        { '^', @"\^" },   // Caret (superscript in some dialects)
        { '.', @"\." },   // Period (can be part of lists when after numbers)
        { ':', @"\:" }    // Colon (definition lists in some dialects)
    };

    var result = new StringBuilder(text.Length * 2); // Pre-allocate for efficiency

    foreach (var c in text) {
        if (markdownChars.TryGetValue(c, out var escaped)) {
            result.Append(escaped);
        } else {
            result.Append(c);
        }
    }

    return result.ToString();
}
Originally created by @schallm on GitHub (Sep 10, 2025). I'm working on writing some markdown from a system that allows user input. I want to include their text, but want to make sure their text doesn't get treated as markdown. I had AI create me a function, but was wondering if Markdig should have a built-in function for this kind of thing. Here is the function I'm using currently. ```c# /// <summary> /// Escapes user-entered text to prevent it from being interpreted as markdown. /// This ensures user content is displayed as literal text rather than formatted markdown. /// </summary> /// <param name="text">The user-entered text to escape</param> /// <returns>The escaped text safe for use in Markdown documents</returns> public static string EscapeMarkdown(string text) { if (string.IsNullOrEmpty(text)) { return text; } // Dictionary of markdown special characters and their escaped equivalents var markdownChars = new Dictionary<char, string> { { '\\', @"\\" }, // Backslash must be first to avoid double-escaping { '*', @"\*" }, // Asterisk (bold/italic) { '_', @"\_" }, // Underscore (bold/italic) { '`', @"\`" }, // Backtick (code) { '#', @"\#" }, // Hash (headers) { '+', @"\+" }, // Plus (lists) { '-', @"\-" }, // Minus (lists, strikethrough) { '=', @"\=" }, // Equals (headers) { '|', @"\|" }, // Pipe (tables) { '{', @"\{" }, // Curly braces (various extensions) { '}', @"\}" }, { '[', @"\[" }, // Square brackets (links, references) { ']', @"\]" }, { '(', @"\(" }, // Parentheses (links) { ')', @"\)" }, { '<', @"\<" }, // Angle brackets (HTML, autolinks) { '>', @"\>" }, // Greater than (blockquotes) { '!', @"\!" }, // Exclamation (images) { '~', @"\~" }, // Tilde (strikethrough) { '^', @"\^" }, // Caret (superscript in some dialects) { '.', @"\." }, // Period (can be part of lists when after numbers) { ':', @"\:" } // Colon (definition lists in some dialects) }; var result = new StringBuilder(text.Length * 2); // Pre-allocate for efficiency foreach (var c in text) { if (markdownChars.TryGetValue(c, out var escaped)) { result.Append(escaped); } else { result.Append(c); } } return result.ToString(); } ```
claunia added the question label 2026-01-29 14:44:46 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/markdig#750