Skip to content

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

@schallm

Description

@schallm

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();
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions